随笔-Dinic
Posted wuyuema
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了随笔-Dinic相关的知识,希望对你有一定的参考价值。
首先是一个很简单的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 ", Res); 40 }
这是Dinic算法的基础。此外为了方便反向边的查找,将存储图的数据结构更改成如下。
struct Edge { int from, to, w; }; vector<int>tab[maxn]; vector<Edge>edg;
相当于是把所有边都按照输入顺序存下来,再分配给各个边。同时,边edg[i]的反向边为edg[i ^ 2]。
接下来是Dinic。
1 struct Edge { 2 int from, to, cap, w; 3 }; 4 vector<int>tab[maxn]; 5 vector<Edge>edg; 6 bool vis[maxn]; 7 int dep[maxn]; 8 int cur[maxn]; 9 void adde(int u, int v, int w) { 10 edg.push_back((edge){u, v, w, 0}); 11 edg.push_back((edge){v, u, 0, 0}); 12 int M = edg.size(); 13 tab[from].push_back(M - 2); 14 tab[to].push_back(M - 1); 15 } 16 bool bfs() { 17 memset(vis, 0, sizeof(vis)); 18 queue<int>q; 19 q.push(s); 20 dep[s] = 0; 21 vis[s] = 1; 22 while (!q.empty()) { 23 int u = q.front(); q.pop(); 24 for (int i = 0; i < tab[u].size(); i++) { 25 Edge& e = edg[tab[u][i]]; 26 if (!vis[e.to] && e.cap > e.w) { 27 vis[e.to] = 1; 28 q.push(e.to); 29 dep[e.to] = dep[u] + 1; 30 } 31 } 32 } 33 return vis[t]; 34 } 35 int dfs(int u, int low) { 36 if (u == t || low == 0) return low; 37 int sum = 0, flow; 38 for (int& i = cur[u]; i < tab[u].size(); i++) { 39 Edge& e = edg[tab[u][i]]; 40 if (dep[u] + 1 == dep[e.to] && (flow = dfs(e.to, min(low, e.cap - e.sum))) > 0) { 41 e.sum += flow; 42 edg[tab[u][i] ^ 1].sum -= flow; 43 sum += flow; 44 low -= flow; 45 if (sum == 0) break; 46 } 47 } 48 return sum; 49 } 50 int maxFlow(int s, int t) { 51 int flow = 0; 52 while (bfs()) { 53 memset(cur, 0, sizeof(cur)); 54 flow += dfs(s, INF); 55 } 56 return flow; 57 }
我写完了。
#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
"
, Res);
}
以上是关于随笔-Dinic的主要内容,如果未能解决你的问题,请参考以下文章