bzoj 1001 狼抓兔子
裸的最小割,直接上模板就行了
1 #define MAXN 1000010UL 2 #include <cstdio> 3 #include <cstring> 4 #define INF 1e9 5 6 using namespace std; 7 8 int n, m, t, hd, tl, S, T, d[MAXN], sn[MAXN], q[MAXN]; 9 10 struct Edge { 11 int hou, nt, zhi; 12 }sg[6000010]; 13 14 int Cal(int i, int j) { 15 return (i-1)*m+j; 16 } 17 18 void Add(int x, int y, int z) { 19 sg[t] = (Edge){y, d[x], z}, d[x] = t ++; 20 sg[t] = (Edge){x, d[y], z}, d[y] = t ++; 21 return; 22 } 23 24 bool Bfs() { 25 memset(sn, 0, sizeof(sn[0])*(T+1)); 26 hd = tl = 0; 27 q[++ tl] = S, sn[S] = 1; 28 while(hd<tl) { 29 int op = q[++ hd]; 30 for(int i = d[op] ; i != -1 ; i = sg[i].nt) { 31 if(sg[i].zhi&&(!sn[sg[i].hou])) { 32 sn[sg[i].hou] = sn[op]+1; 33 q[++ tl] = sg[i].hou; 34 if(sg[i].hou==T) return true; 35 } 36 } 37 } 38 return false; 39 } 40 41 int MIN(int A, int B) { return A<B?A:B; } 42 43 int Dfs(int op, int fw) { 44 if(op==T) return fw; 45 int tmp = fw, k; 46 for(int i = d[op] ; i != -1 ; i = sg[i].nt) { 47 if(sg[i].zhi&&tmp&&sn[sg[i].hou]==sn[op]+1) { 48 k = Dfs(sg[i].hou, MIN(sg[i].zhi, tmp)); 49 if(!k) { 50 sn[sg[i].hou] = 0; 51 continue; 52 } 53 tmp -= k; 54 sg[i].zhi -= k, sg[i^1].zhi += k; 55 } 56 } 57 return fw-tmp; 58 } 59 60 int main() { 61 memset(d, -1, sizeof(d)); 62 int x; 63 scanf("%d%d", &n, &m); 64 for(int i = 1 ; i <= n ; ++ i) { 65 for(int j = 1 ; j < m ; ++ j) { 66 scanf("%d", &x); 67 Add(Cal(i, j), Cal(i, j+1), x); 68 } 69 } 70 for(int i = 1 ; i < n ; ++ i) { 71 for(int j = 1 ; j <= m ; ++ j) { 72 scanf("%d", &x); 73 Add(Cal(i, j), Cal(i+1, j), x); 74 } 75 } 76 for(int i = 1 ; i < n ; ++ i) { 77 for(int j = 1 ; j < m ; ++ j) { 78 scanf("%d", &x); 79 Add(Cal(i, j), Cal(i+1, j+1), x); 80 } 81 } 82 S = Cal(1, 1), T = Cal(n, m); 83 int fw = 0, p; 84 while(Bfs()) while(p = Dfs(S, INF)) fw += p; 85 printf("%d", fw); 86 return 0; 87 }