刚刚复习了最大流算法,温习了 Edmons-Karp 算法的思想和简单步骤后,第一次写的是用结构体包装节点和边,
不过后来发现这样虽然一定程度上使代码更加容易理解,但是调用变量的语句长了许多,于是还是采用数据的方式。
这样速度会快不少。以下是我写的最大流算法。发现错误或不足之处希望留言提醒更正。
#include<iostream>
#include<stdio.h>
#include<string>
#include<queue>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 200;
const int bigint = 1e9;
int flow[maxn][maxn]; //一条边的当前流量,反向时为负数
int cap[maxn][maxn]; //一条边的最大容量
int prenode[maxn]; //用于记录到终点的路线
int potential[maxn]; //容量增加的潜力
//node munber, edge number, starting point and destination
int n, m, start, dest;
int maxflow; //answer
//初始化数值,每次BFS后都要清理potential
void clear(){
memset(potential, 0, sizeof(potential));
potential[start] = bigint;
}
//获取输入数据
void getdata(){
memset(flow, 0, sizeof(flow));
memset(cap, 0, sizeof(cap));
cin >> n >> m >> start >> dest;
for (int i = 0; i < m; i++){
int from, to, val;
cin >> from >> to >> val;
cap[from][to] = cap[to][from] = val;
}
maxflow = 0;
}
int main(){
getdata();
queue<int>temp;
while (true){ //不断bfs直至不能再找到增加流量的路
clear(); //每次BFS后都要清理potential[]
temp.push(start);
while ( temp.empty() == false){ //bfs寻找增广路
int nowat = temp.front();
temp.pop();
for (int i = 0; i < n; i++){ //每个点只访问一次,每次访问后更新其流量潜力,放到队列
if (potential[i] == 0 && flow[nowat][i] < cap[nowat][i]){
potential[i] = min(potential[nowat], cap[nowat][i] - flow[nowat][i]);
prenode[i] = nowat;
temp.push(i);
}
}
}
if (potential[dest] == 0) break; //说明了已经找不到去终点的流,退出
for (int u = dest; u != start; u = prenode[u]){ //进入下一次bfs前先更新当前流量,
int l = prenode[u];
flow[u][l] -= potential[dest];
flow[l][u] += potential[dest];
}
maxflow += potential[dest];
}
cout << maxflow << endl;
return 0;
}
/*
input example:
4 4 0 3
0 1 5
0 2 20
2 3 10
1 3 100
output : 15
*/