首先是一个很简单的dfs求最大流算法(FF),代码如下
1 #include <bits/stdc++.h> 2 #define MAXN 300 3 #define INF 19930317 4 5 int c[MAXN][MAXN]; 6 int s, t, i, k, u, v, w, n, m; 7 int flow, Res; 8 int vis[MAXN]; 9 10 int dfs(int u, int low) { 11 int i, flow; 12 if (u == t) 13 return low; 14 if (vis[u]) 15 return 0; 16 vis[u] = 1; 17 for (i = 1; i <= n; i++) 18 if (c[u][i] && (flow = dfs(i, low < c[u][i] ? low : c[u][i]))) { 19 c[u][i] -= flow; 20 c[i][u] += flow; 21 return flow; 22 } 23 return 0; 24 } 25 26 27 int main() { 28 scanf("%d%d", &m, &n); 29 for (i = 1; i <= m; i++) { 30 scanf("%d%d%d", &u, &v, &w); 31 c[u][v] += w; 32 } 33 s = 1; 34 t = n; 35 while (flow = dfs(s, INF)) { 36 Res += flow; 37 memset(vis, 0, sizeof(vis)); 38 } 39 printf("%d\n", Res); 40 }
这是Dinic算法的基础。此外为了方便反向边的查找,将存储图的数据结构更改成如下。
struct Edge { int from, to, w; }; vector<int>tab[maxn]; vector<Edge>edg;
相当于是把所有边都按照输入顺序存下来,再分配给各个边。同时,边edg[i]的反向边为edg[i ^ 2]。
接下来是Dinic。
1 int n, m, s, t; 2 int dep[maxn], p[maxn]; 3 bool bfs() { 4 memset(dep, 0, sizeof(dep)); 5 dep[s] = 1; 6 queue<int> q; 7 q.push(s); 8 while (!q.empty()) { 9 int u = q.front(); q.pop(); 10 for (int i = 0; i < G[u].size(); i++) { 11 Edge& e = E[G[u][i]]; 12 if (!dep[e.to] && e.flow) { 13 dep[e.to] = dep[u] + 1; 14 q.push(e.to); 15 if (e.to == t) return 1; 16 } 17 } 18 } 19 return dep[t]; 20 } 21 22 int dfs(int u, int low) { 23 if (u == t || low <= 0) return low; 24 int sum = 0, flow; 25 for (int& i = p[u]; i < G[u].size(); i++) { 26 Edge& e = E[G[u][i]]; 27 if ((dep[e.to] == dep[u] + 1) && (e.flow != 0)) { 28 int flow = dfs(e.to, min(low, e.flow)); 29 e.flow -= flow; 30 E[G[u][i]^1].flow += flow; 31 sum += flow; 32 low -= flow; 33 if (low <= 0) break; 34 } 35 } 36 return sum; 37 } 38 39 int dinic() { 40 int ans = 0; 41 while (bfs()) { 42 memset(p, 0, sizeof(p)); 43 ans += dfs(s, inf); 44 } 45 return ans; 46 }
我写完了。
#include <bits/stdc++.h>#define MAXN 300#define INF 19930317int c[MAXN][MAXN];int s, t, i, k, u, v, w, n, m;int flow, Res;int vis[MAXN];int dfs(int u, int low) { int i, flow; if (u == t) return low; if (vis[u]) return 0; vis[u] = 1; for (i = 1; i <= n; i++) if (c[u][i] && (flow = dfs(i, low < c[u][i] ? low : c[u][i]))) { c[u][i] -= flow; c[i][u] += flow; return flow; } return 0;}int main() { scanf("%d%d", &m, &n); for (i = 1; i <= m; i++) { scanf("%d%d%d", &u, &v, &w); c[u][v] += w; } s = 1; t = n; while (flow = dfs(s, INF)) { Res += flow; memset(vis, 0, sizeof(vis)); } printf("%d\n", Res);}
浙公网安备 33010602011771号