基于残留网络与FF算法的改进-EK算法,核心是将一条边的单向残留容量的减少看做反向残留流量的增加。
//网络流 //EK算法 //Time:16Ms Memory:348K #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> using namespace std; #define MAX 205 #define INF 0x3f3f3f3f int n, m; int res[MAX][MAX]; int pre[MAX]; bool v[MAX]; bool bfs(int s,int t) //寻找s->t的增广路 { memset(v, false , sizeof(v)); memset(pre, -1, sizeof(pre)); queue<int> q; q.push(s); v[s] = true; while (!q.empty()) { int cur = q.front(); q.pop(); for (int i = 1; i <= n; i++) { if (!v[i] && res[cur][i]) { pre[i] = cur; if (i == t) return true; //找到增广路 q.push(i); v[i] = true; } } } return false; } int EK(int s, int t) { int maxFlow = 0; while (bfs(s, t)) { int mind = INF; //最小可改进量 for (int i = t; i != s; i = pre[i]) mind = min(mind, res[pre[i]][i]); for (int i = t; i != s; i = pre[i]) { res[pre[i]][i] -= mind; res[i][pre[i]] += mind; } maxFlow += mind; } return maxFlow; } int main() { //freopen("in.txt", "r", stdin); while (~scanf("%d%d", &m, &n)) { memset(res, 0, sizeof(res)); int u, v, c; for (int i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &c); res[u][v] += c; } printf("%d\n", EK(1, n)); } return 0; }