1 #include <cstdlib> 2 #include <algorithm> 3 #include <cstring> 4 #include <iostream> 5 #include <cstdio> 6 #include <vector> 7 8 using namespace std; 9 10 const int N = 100 + 5; 11 const int oo = 0x3f3f3f3f; 12 13 struct Edge { 14 int from, to, cap, flow; 15 }; 16 17 struct Dinic { 18 int n, m, s, t; 19 int dis[N], cur[N], que[N << 1]; 20 bool vis[N]; 21 vector <Edge> edges; 22 vector <int> G[N]; 23 24 void add(int from, int to, int cap) { 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 bool bfs() { 33 int head = 1, tail = 1; 34 35 memset(vis, false, sizeof vis); 36 dis[s] = 0; vis[s] = true; que[head] = s; 37 while(head <= tail) { 38 int x = que[head]; 39 40 for(int i = 0; i < (signed) G[x].size(); ++ i) { 41 Edge &e = edges[G[x][i]]; 42 43 if(!vis[e.to] && e.cap > e.flow) { 44 vis[e.to] = true; 45 dis[e.to] = dis[x] + 1; 46 que[++ tail] = e.to; 47 } 48 } 49 ++ head; 50 } 51 return vis[t]; 52 } 53 54 int dfs(int x, int a) { 55 if(x == t || a == 0) return a; 56 57 int flw = 0, f; 58 59 for(int &i = cur[x]; i < (signed) G[x].size(); ++ i) { 60 Edge &e = edges[G[x][i]]; 61 62 if(dis[e.to] == dis[x] + 1 && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0) { 63 e.flow += f; edges[G[x][i] ^ 1].flow -= f; flw += f; a -= f; 64 if(a == 0) break; 65 } 66 } 67 return flw; 68 } 69 70 int MaxFlow(int s, int t) { 71 this->s = s; this->t = t; 72 73 int flw = 0; 74 75 while(bfs()) { 76 memset(cur, 0, sizeof cur); 77 flw += dfs(s, oo); 78 } 79 return flw; 80 } 81 }net; 82 83 int n, M[N]; 84 85 int main() { 86 #ifndef ONLINE_JUDGE 87 freopen("maxflowb.in", "r", stdin); 88 freopen("maxflowb.out", "w", stdout); 89 #endif 90 91 int Up, Down; 92 93 scanf("%d", &n); net.n = n + 1; 94 for(int i = 1; i <= n; ++ i) { 95 for(int j = 1; j <= n; ++ j) { 96 scanf("%d%d", &Down, &Up); 97 M[i] -= Down; M[j] += Down; 98 net.add(i, j, Up - Down); 99 } 100 } 101 net.add(n, 1, oo); 102 for(int i = 1; i <= n; ++ i) { 103 if(M[i] > 0) { 104 net.add(0, i, M[i]); 105 } 106 else if(M[i] < 0){ 107 net.add(i, n + 1, -M[i]); 108 } 109 } 110 net.MaxFlow(0, n + 1); 111 printf("%d ", net.MaxFlow(1, n)); 112 113 #ifndef ONLINE_JUDGE 114 fclose(stdin); fclose(stdout); 115 #endif 116 return 0; 117 }
连边方式见图。