Dinic:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int MAXN = 1e5 + 5, inf = 0x7f7f7f7f; 6 7 struct edge { 8 int to, nxt, cap; 9 } edges[MAXN << 1]; 10 11 int head[MAXN], level[MAXN], cur[MAXN], n, m, s, t, cnt = 0; 12 13 inline void addedge(int from, int to, int cap) { 14 edges[cnt].to = to, edges[cnt].nxt = head[from]; 15 edges[cnt].cap = cap, head[from] = cnt++; 16 edges[cnt].to = from, edges[cnt].nxt = head[to]; 17 edges[cnt].cap = 0, head[to] = cnt++; 18 } 19 20 queue<int> que; 21 int getlevel() { 22 memset(level, 0, sizeof(level)); 23 for(int i = 1; i <= n; i++) cur[i] = head[i]; 24 level[s] = 1; que.push(s); 25 while(!que.empty()) { 26 for(int i = head[que.front()]; i != -1; i = edges[i].nxt) 27 if(!level[edges[i].to] && edges[i].cap) { 28 level[edges[i].to] = level[que.front()] + 1; 29 que.push(edges[i].to); 30 } 31 que.pop(); 32 } 33 return level[t]; 34 } 35 36 int impflow(int now, int ff) { 37 if(now == t) return ff; 38 int flow = 0, resi; 39 for(int &i = cur[now]; i != -1; i = edges[i].nxt) 40 if(edges[i].cap && level[edges[i].to] > level[now] && 41 (resi = impflow(edges[i].to, min(ff, edges[i].cap)))) { 42 edges[i].cap -= resi; edges[i ^ 1].cap += resi; 43 flow += resi; ff -= resi; 44 if(!ff) break; 45 } 46 return flow; 47 } 48 49 int getmaxflow() { 50 int maxflow = 0; 51 while(getlevel()) maxflow += impflow(s, inf); 52 return maxflow; 53 } 54 55 int main() { 56 memset(head, 0xff, sizeof(head)); 57 int x, y, z; 58 scanf("%d%d%d%d", &n, &m, &s, &t); 59 while(m--) scanf("%d%d%d", &x, &y, &z), addedge(x, y, z); 60 printf("%d\n", getmaxflow()); 61 return 0; 62 }