很久以前,看到家乡洪水肆虐,大禹决心要把洪水引到大海里,因此带领众人修建立了一套水沟系统。他们在每条水沟都装了阀门来控制水的流量。他们设计了每条水沟每分钟的排水量,以及水沟的整体布局。洪水从池塘流出,最后汇入大海。请确定洪水从家乡流入大海的最大流量。 输入格式: 第一行包含两个整数N和M,分别表示水沟数量和水沟的交叉点数量,其中交叉点1代表家乡,交叉点M是大海。后面N行,每行三个整数,s,e,c,其中s,e表示交叉点且水从s流向e,最大流量是c(0到10000之间)。 输出格式: 输出排出水的最大流量。。直接给出c++代码
时间: 2024-03-30 20:36:12 浏览: 97
好的,以下是使用 Edmonds-Karp 算法求解最大流的 C++ 代码实现:
```c++
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int N = 210, M = 20010;
int n, m, S, T;
int h[N], e[M], f[M], ne[M], idx;
int d[N], cur[N];
vector<int> p;
void add(int a, int b, int c) {
e[idx] = b, f[idx] = c, ne[idx] = h[a], h[a] = idx++;
e[idx] = a, f[idx] = 0, ne[idx] = h[b], h[b] = idx++;
}
bool bfs() {
memset(d, -1, sizeof d);
queue<int> q;
q.push(S);
d[S] = 0, cur[S] = h[S];
while (q.size()) {
int t = q.front();
q.pop();
for (int i = h[t]; ~i; i = ne[i]) {
int ver = e[i];
if (d[ver] == -1 && f[i]) {
d[ver] = d[t] + 1;
cur[ver] = h[ver];
if (ver == T) return true;
q.push(ver);
}
}
}
return false;
}
int find(int u, int limit) {
if (u == T) return limit;
int flow = 0;
for (int i = cur[u]; ~i && flow < limit; i = ne[i]) {
cur[u] = i;
int ver = e[i];
if (d[ver] == d[u] + 1 && f[i]) {
int t = find(ver, min(f[i], limit - flow));
if (!t) d[ver] = -1;
f[i] -= t, f[i ^ 1] += t, flow += t;
}
}
return flow;
}
int dinic() {
int r = 0, flow;
while (bfs()) while (flow = find(S, 0x3f3f3f3f)) r += flow;
return r;
}
int main() {
memset(h, -1, sizeof h);
cin >> n >> m;
S = 1, T = m;
while (n--) {
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
}
cout << dinic() << endl;
return 0;
}
```
其中,`h` 数组表示每个节点的第一条边在 `e` 数组中的下标,`ne` 数组表示同一节点的下一条边在 `e` 数组中的下标,`f` 数组表示每条边的剩余容量。
在 `add` 函数中,我们根据输入的起点、终点、最大流量构建原图。
在 `bfs` 函数中,我们使用 BFS 搜索增广路径,并记录每个节点的深度和当前搜索到的第一条边在 `e` 数组中的下标。
在 `find` 函数中,我们沿着增广路径递归查找最小剩余容量,并更新每条边的剩余容量。
最后,在 `dinic` 函数中,我们重复进行 BFS 和查找增广路径的操作,直到无法找到增广路径为止,此时的流量即为最大流量。
最后输出答案即可。
阅读全文