在 C++ 中查找流网络中的最小 s-t 割
假设我们有以下流网络。众所周知,s-t 割是指将源节点 s 和汇点 t 分到不同子集中所需的割,并且它包含从源集到汇点侧的边。此处,s-t 割的容量由割集中每条边的容量之和表示。在这里,我们必须找到给定网络的最小容量 s-t 割。此处,预期输出是最小割的所有边。
因此,如果输入类似于

则输出将为 [(1,3), (4,3), (4,5)]
为了解决这个问题,我们将遵循以下步骤:
节点数 NODES = 6
定义一个函数 bfs(),它将接收图、源节点 src、汇点 sink 和数组 par 作为参数。
定义一个大小为 NODES 的数组 vis,并将其全部填充为 0。
定义一个队列 que。
将源节点 src 插入队列 que 中。
将 vis[src] 设置为 true,并将 par[src] 设置为 -1。
当 (队列 que 不为空) 时,执行以下操作:
u1 := 队列 que 的第一个元素。
从队列 que 中删除该元素。
初始化 v1 := 0,当 v1 < NODES 时,更新 (将 v1 增加 1),执行以下操作:
如果 vis[v1] 为假且 graph[u1, v1] > 0,则执行以下操作:
将 v1 插入队列 que 中。
par[v1] := u1。
vis[v1] := true。
当 vis[sink] 为真时,返回 true。
定义一个函数 dfs(),它将接收图、源节点 src 和数组 vis 作为参数。
vis[src] := true。
初始化 i := 0,当 i < NODES 时,更新 (将 i 增加 1),执行以下操作:
如果 graph[src, i] 不为零且 vis[i] 为假,则执行以下操作:
dfs(graph, i, vis)。
从主方法中,执行以下操作:
定义一个数组 temp_graph 并将 graph 复制到其中。
定义一个大小为 NODES 的数组 par。
当 bfs(temp_graph, src, sink, par) 为真时,执行以下操作:
path_flow := 无穷大。
初始化 v := sink,当 v 不等于 src 时,更新 v:=par[v],执行以下操作:
u := par[v]。
path_flow := path_flow 和 temp_graph[u, v] 中的最小值。
初始化 v := sink,当 v 不等于 src 时,更新 v:=par[v],执行以下操作:
u := par[v]。
temp_graph[u, v] := temp_graph[u, v] - path_flow。
temp_graph[v, u] := temp_graph[v, u] + path_flow。
定义一个大小为 NODES 的数组 vis,并将其全部填充为 false。
dfs(temp_graph, src, vis)。
初始化 i := 0,当 i − NODES 时,更新 (将 i 增加 1),执行以下操作:
初始化 j := 0,当 j − NODES 时,更新 (将 j 增加 1),执行以下操作:
如果 vis[i] 不为零且 vis[j] 为假且 graph[i, j] 不为零,则执行以下操作:
显示 (i, j) 作为边。
返回。
示例 (C++)
让我们看看以下实现以更好地理解:
#include <bits/stdc++.h>
using namespace std;
#define NODES 6
int bfs(int graph[NODES][NODES], int src, int sink, int par[]) {
bool vis[NODES];
memset(vis, 0, sizeof(vis));
queue <int> que;
que.push(src);
vis[src] = true;
par[src] = -1;
while (!que.empty()) {
int u1 = que.front();
que.pop();
for (int v1=0; v1<NODES; v1++){
if (vis[v1]==false && graph[u1][v1] > 0) {
que.push(v1);
par[v1] = u1;
vis[v1] = true;
}
}
}
return (vis[sink] == true);
}
void dfs(int graph[NODES][NODES], int src, bool vis[]) {
vis[src] = true;
for (int i = 0; i < NODES; i++)
if (graph[src][i] && !vis[i])
dfs(graph, i, vis);
}
void minCut(int graph[NODES][NODES], int src, int sink) {
int u, v;
int temp_graph[NODES][NODES];
for (u = 0; u < NODES; u++)
for (v = 0; v < NODES; v++)
temp_graph[u][v] = graph[u][v];
int par[NODES];
while (bfs(temp_graph, src, sink, par)){
int path_flow = INT_MAX;
for (v=sink; v!=src; v=par[v]) {
u = par[v];
path_flow = min(path_flow, temp_graph[u][v]);
}
for (v=sink; v != src; v=par[v]) {
u = par[v];
temp_graph[u][v] -= path_flow;
temp_graph[v][u] += path_flow;
}
}
bool vis[NODES];
memset(vis, false, sizeof(vis));
dfs(temp_graph, src, vis);
for (int i = 0; i < NODES; i++)
for (int j = 0; j < NODES; j++)
if (vis[i] && !vis[j] && graph[i][j])
cout << "("<< i << ", " << j << ")" << endl;
return;
}
int main() {
int graph1[NODES][NODES] = {
{0, 17, 14, 0, 0, 0},
{0, 0, 11, 13, 0, 0},
{0, 5, 0, 0, 15, 0},
{0, 0, 9, 0, 0, 21},
{0, 0, 0, 8, 0, 5},
{0, 0, 0, 0, 0, 0}
};
minCut(graph1, 0, 5);
}输入
{{0, 17, 14, 0, 0, 0},
{0, 0, 11, 13, 0, 0},
{0, 5, 0, 0, 15, 0},
{0, 0, 9, 0, 0, 21
{0, 0, 0, 8, 0, 5},
{0, 0, 0, 0, 0, 0}};输出
(1, 3) (4, 3) (4, 5)
数据结构
网络
关系数据库管理系统
操作系统
Java
iOS
HTML
CSS
Android
Python
C 编程
C++
C#
MongoDB
MySQL
Javascript
PHP