Dinic 模板
1 struct Edge { 2 int from, to, cap, flow; 3 }; 4 struct Dinic { 5 int n, m, s, t; 6 vector<Edge>edges; 7 vector<int>G[MAXN]; 8 bool vis[MAXN]; 9 int d[MAXN]; 10 int cur[MAXN]; 11 void init(int n) { 12 for (int i = 0; i < MAXN; i++) G[i].clear(); 13 edges.clear();memset(d,0,sizeof(d)); 14 } 15 void AddEdge(int from, int to, int cap) { 16 edges.push_back({ from, to, cap, 0 }); 17 edges.push_back({ to, from, 0, 0 }); 18 m = edges.size(); 19 G[from].push_back(m - 2); 20 G[to].push_back(m - 1); 21 } 22 bool BFS() { 23 int x, i; 24 memset(vis, 0, sizeof(vis)); 25 queue<int>Q; 26 Q.push(s); 27 d[s] = 0; 28 vis[s] = 1; 29 while (!Q.empty()) { 30 x = Q.front(), Q.pop(); 31 for (i = 0; i < G[x].size(); i++) { 32 Edge & e = edges[G[x][i]]; 33 if (!vis[e.to] && e.cap > e.flow) { 34 vis[e.to] = 1; 35 d[e.to] = d[x] + 1; 36 Q.push(e.to); 37 } 38 } 39 } 40 return vis[t]; 41 } 42 int DFS(int x, int a) { 43 if (x == t || a == 0) 44 return a; 45 int flow = 0, f; 46 for (int &i = cur[x]; i < G[x].size(); i++) { 47 Edge & e = edges[G[x][i]]; 48 if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) { 49 e.flow += f; 50 edges[G[x][i] ^ 1].flow -= f; 51 flow += f; 52 a -= f; 53 if (a == 0) 54 break; 55 } 56 } 57 return flow; 58 } 59 int Maxflow(int s, int t) { 60 this->s = s, this->t = t; 61 int flow = 0; 62 while (BFS()) { 63 memset(cur, 0, sizeof(cur)); 64 flow += DFS(s, INF); 65 } 66 return flow; 67 } 68 };
Edmonds Karp模板
1 const int maxn=; 2 const int inf=0x3f3f3f3f; 3 struct Edge 4 { 5 int from,to,cap,flow; 6 Edge(int u,int v,int c,int f): from(u),to(v),cap(c),flow(f) {} 7 }; 8 9 struct EdmondsKarp 10 { 11 int n,m; 12 vector<Edge> edges; 13 vector<int> G[maxn]; 14 int a[maxn]; 15 int p[maxn]; 16 17 void init(int n) 18 { 19 for(int i=0;i<n;i++) G[i].clear(); 20 edges.clear(); 21 } 22 23 void AddEdge(int from,int to,int cap) 24 { 25 edges.push_back(Edge(from,to,cap,0)); 26 edges.push_back(Edge(to,from,0,0)); 27 m=edges.size(); 28 G[from].push_back(m-2); 29 G[to].push_back(m-1); 30 } 31 32 int Maxflow(int s,int t) 33 { 34 int flow=0; 35 while(1) 36 { 37 memset(a,0,sizeof(a)); 38 queue<int> Q; 39 Q.push(s); 40 a[s]=inf; 41 while(!Q.empty()) 42 { 43 int x=Q.front();Q.pop(); 44 for(int i=0;i<G[x].size();i++) 45 { 46 Edge& e=edges[G[x][i]]; 47 if(!a[e.to]&&e.cap>e.flow) 48 { 49 p[e.to]=G[x][i]; 50 a[e.to]=min(a[x],e.cap-e.flow); 51 Q.push(e.to); 52 } 53 } 54 if(a[t]) break; 55 } 56 if(!a[t]) break; 57 for(int u=t;u!=s;u=edges[p[u]].from) 58 { 59 edges[p[u]].flow+=a[t]; 60 edges[p[u]^1].flow-=a[t]; 61 } 62 flow+=a[t]; 63 } 64 return flow; 65 } 66 };
对于最小割来说,在算法结束后,令已经标号的结点(a[u]>0的结点)集合为S,其他集合为T=V-S,则(S,T)是图 s-t 的最小割
ISAP,附带Mincut方案
1 #include<bits/stdc++.h> 2 #define REP(i, a, b) for(int i = (a); i < (b); i++) 3 #define MEM(a,x) memset(a,x,sizeof(a)) 4 #define INF 0x3f3f3f3f 5 #define MAXN 100000+10 6 using namespace std; 7 8 struct Edge 9 { 10 int from, to, cap, flow; 11 Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f) {} 12 }; 13 14 struct ISAP 15 { 16 int n, m, s, t; 17 vector<Edge>edges; 18 vector<int>G[MAXN]; 19 bool vis[MAXN]; 20 int d[MAXN], cur[MAXN]; 21 int p[MAXN], num[MAXN];//比Dinic算法多了这两个数组,p数组标记父亲结点,num数组标记距离d[i]存在几个 22 void addedge(int from, int to, int cap) 23 { 24 edges.push_back(Edge(from, to, cap, 0)); 25 edges.push_back(Edge(to, from, 0, 0)); 26 int m = edges.size(); 27 G[from].push_back(m - 2); 28 G[to].push_back(m - 1); 29 } 30 31 void init(int n) { 32 this->n = n; 33 for (int i = 0; i < n; i++) { 34 G[i].clear(); 35 } 36 edges.clear(); 37 } 38 39 int Augumemt() 40 { 41 int x = t, a = INF; 42 while (x != s)//找最小的残量值 43 { 44 Edge&e = edges[p[x]]; 45 a = min(a, e.cap - e.flow); 46 x = edges[p[x]].from; 47 } 48 x = t; 49 while (x != s)//增广 50 { 51 edges[p[x]].flow += a; 52 edges[p[x] ^ 1].flow -= a;//更新反向边。 53 x = edges[p[x]].from; 54 } 55 return a; 56 } 57 void BFS()//逆向进行bfs 58 { 59 memset(vis, 0, sizeof(vis)); 60 queue<int>q; 61 q.push(t); 62 d[t] = 0; 63 vis[t] = 1; 64 while (!q.empty()) 65 { 66 int x = q.front(); q.pop(); 67 int len = G[x].size(); 68 for (int i = 0; i < len; i++) 69 { 70 Edge&e = edges[G[x][i]]; 71 if (!vis[e.from] && e.cap > e.flow) 72 { 73 vis[e.from] = 1; 74 d[e.from] = d[x] + 1; 75 q.push(e.from); 76 } 77 } 78 } 79 } 80 81 int Maxflow(int s, int t)//根据情况前进或者后退,走到汇点时增广 82 { 83 this->s = s; 84 this->t = t; 85 int flow = 0; 86 BFS(); 87 memset(num, 0, sizeof(num)); 88 for (int i = 0; i < n; i++) 89 num[d[i]]++; 90 int x = s; 91 memset(cur, 0, sizeof(cur)); 92 while (d[s] < n) 93 { 94 if (x == t)//走到了汇点,进行增广 95 { 96 flow += Augumemt(); 97 x = s;//增广后回到源点 98 } 99 int ok = 0; 100 for (int i = cur[x]; i < G[x].size(); i++) 101 { 102 Edge&e = edges[G[x][i]]; 103 if (e.cap > e.flow&&d[x] == d[e.to] + 1) 104 { 105 ok = 1; 106 p[e.to] = G[x][i];//记录来的时候走的边,即父边 107 cur[x] = i; 108 x = e.to;//前进 109 break; 110 } 111 } 112 if (!ok)//走不动了,撤退 113 { 114 int m = n - 1;//如果没有弧,那么m+1就是n,即d[i]=n 115 for (int i = 0; i < G[x].size(); i++) 116 { 117 Edge&e = edges[G[x][i]]; 118 if (e.cap > e.flow) 119 m = min(m, d[e.to]); 120 } 121 if (--num[d[x]] == 0)break;//如果走不动了,且这个距离值原来只有一个,那么s-t不连通,这就是所谓的“gap优化” 122 num[d[x] = m + 1]++; 123 cur[x] = 0; 124 if (x != s) 125 x = edges[p[x]].from;//退一步,沿着父边返回 126 } 127 } 128 return flow; 129 } 130 vector<int>Mincut() { 131 BFS(); 132 vector<int>ans; 133 for (int i = 0; i < edges.size(); i++) { 134 Edge& e = edges[i]; 135 if (!vis[e.from] && vis[e.to] && e.cap > 0) 136 ans.push_back(i); 137 } 138 return ans; 139 } 140 };