网络流二·最大流最小割定理 HihoCoder - 1378
网络流二·最大流最小割定理
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxv = 1010; 4 const int maxe = 20010; 5 const int inf = 0x3f3f3f3f; 6 struct Edge{ 7 int u, v, nex; 8 int cap, flow; 9 Edge(int u=0, int v=0, int nex=0, int cap=0, int flow=0): 10 u(u), v(v), nex(nex), cap(cap), flow(flow){} 11 }e[maxe<<1]; 12 int head[maxv]; 13 int cnt; 14 void init(){ 15 memset(head, -1, sizeof(head)); 16 cnt = 0; 17 } 18 19 void add(int u, int v, int cap){ 20 e[cnt] = Edge(u, v, head[u], cap, 0); 21 head[u] = cnt++; 22 e[cnt] = Edge(v, u, head[v], 0, 0); 23 head[v] = cnt++; 24 } 25 26 int d[maxv], num[maxv], cur[maxv], p[maxv]; 27 int vis[maxv]; 28 int S, T; 29 int N; 30 31 void bfs(){ 32 memset(d, -1, sizeof(d)); 33 memset(vis, 0, sizeof(vis)); 34 queue<int> q; 35 q.push(T); 36 vis[T] = 1; 37 d[T] = 0; 38 while(!q.empty()){ 39 int u = q.front(); 40 q.pop(); 41 for(int i = head[u]; ~i; i = e[i].nex){ 42 int id = i&(-2); //正边 43 int v = e[id].u; 44 if(!vis[v] && e[id].cap > e[id].flow){ 45 vis[v] = 1; 46 d[v] = d[u] + 1; 47 q.push(v); 48 } 49 } 50 } 51 } 52 53 int augment(){ 54 int u = T; 55 int a = inf; 56 while(u!=S){ 57 int id = p[u]; 58 a = min(a, e[id].cap - e[id].flow); 59 u = e[id].u; 60 } 61 u = T; 62 while(u!=S){ 63 int id = p[u]; 64 e[id].flow += a; 65 e[id^1].flow -= a; 66 u = e[id].u; 67 } 68 return a; 69 } 70 71 int ISAP(){ 72 bfs(); 73 int flow = 0; 74 memset(num, 0, sizeof(num)); 75 for(int i = 0; i < N; i++){ 76 cur [i] = head[i]; 77 if(~d[i]) num[d[i]]++; 78 } 79 int u = S; 80 while(d[S] < N){ 81 if(u == T){ 82 flow += augment(); 83 u = S; 84 } 85 int ok = 0; 86 for(int i = cur[u]; ~i; i = e[i].nex){ 87 int v = e[i].v; 88 if(d[u] == d[v]+1 && e[i].cap > e[i].flow){ 89 p[v] = i; 90 ok = 1; 91 cur[u] = i; 92 u = v; 93 break; 94 } 95 } 96 if(!ok){ 97 int m = N-1; 98 for(int i = head[u]; ~i; i = e[i].nex){ 99 if(e[i].cap > e[i].flow && ~d[e[i].v]) m = min(m, d[e[i].v]); 100 } 101 if(--num[d[u]] == 0) break; 102 num[d[u]=m+1]++; 103 cur[u] = head[u]; 104 if(u != S) u = e[p[u]].u; 105 } 106 } 107 return flow; 108 } 109 vector<int> V; 110 void dfs(int u){ 111 for(int i = head[u]; ~i; i = e[i].nex){ 112 int v = e[i].v; 113 if(!vis[v]&&e[i].flow < e[i].cap){ 114 V.push_back(v); 115 vis[v] = 1; 116 dfs(v); 117 } 118 } 119 } 120 int main(){ 121 init(); 122 int n, m; 123 scanf("%d %d", &n, &m); 124 int u, v, cap; 125 for(int i = 0; i < m; i++){ 126 scanf("%d %d %d", &u, &v, &cap); 127 u--;v--; 128 add(u, v, cap); 129 } 130 S = 0; 131 T = n-1; 132 N = n; 133 int ans = ISAP(); 134 V.push_back(S); 135 memset(vis, 0, sizeof(vis)); 136 vis[S] = 1; 137 dfs(S); 138 printf("%d %d\n%d",ans, V.size(), V[0]+1); 139 for(int i = 1; i < V.size(); i++){ 140 printf(" %d", V[i]+1); 141 } 142 puts(""); 143 }