首先是一个很简单的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 19930317
int
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);
}