P2774 方格取数问题
1 #include<bits/stdc++.h> 2 #define _for(i,a,b) for(register int i = (a);i < b;i ++) 3 #define _rep(i,a,b) for(register int i = (a);i > b;i --) 4 #define INF 0x3f3f3f3f 5 #define MOD 100000000 6 #define maxn 1000003 7 #define pb push_back 8 #define debug() printf("Miku Check OK!\n") 9 typedef long long ll; 10 11 using namespace std; 12 typedef pair<int,int> P; 13 inline ll read() 14 { 15 ll ans = 0; 16 char ch = getchar(), last = ' '; 17 while(!isdigit(ch)) last = ch, ch = getchar(); 18 while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar(); 19 if(last == '-') ans = -ans; 20 return ans; 21 } 22 inline void write(ll x) 23 { 24 if(x < 0) x = -x, putchar('-'); 25 if(x >= 10) write(x / 10); 26 putchar(x % 10 + '0'); 27 } 28 int ver[maxn],Next[maxn],head[maxn],val[maxn]; 29 int d[maxn]; 30 int n,m,s,t,tot,maxflow; 31 const int N = 20000; 32 void add(int x,int y,int w) 33 { 34 ver[++tot] = y,Next[tot] = head[x],head[x] = tot,val[tot] = w; 35 } 36 bool bfs() 37 { 38 memset(d,0,sizeof(d)); 39 queue<int> q; 40 q.push(s); 41 d[s] = 1; 42 while(!q.empty()) 43 { 44 int x = q.front(); 45 q.pop(); 46 for(int i = head[x]; i; i = Next[i]) 47 if(val[i] && !d[ver[i]]) 48 { 49 q.push(ver[i]); 50 d[ver[i]] = d[x]+1; 51 if(ver[i]==t) 52 return true; 53 } 54 } 55 return false; 56 } 57 int dinic(int x,int flow) 58 { 59 if(x==t) return flow; 60 // k为子节点增量 61 int rest = flow, k; 62 for(int i = head[x]; i && rest; i = Next[i]) 63 { 64 if(val[i] && d[ver[i]] == d[x]+1) 65 { 66 k = dinic(ver[i],min(rest,val[i])); 67 if(!k) d[ver[i]] = 0; 68 val[i] -= k; 69 val[i^1] += k; 70 rest -= k; 71 } 72 } 73 return flow - rest; 74 } 75 int a[103][103]; 76 int getHash(int x,int y) 77 { 78 return x*m+y; 79 } 80 int main() 81 { 82 n = read(); 83 m = read(); 84 s = 0; 85 t = 2*N+1; 86 tot = 1; 87 maxflow = 0; 88 int zong = 0; 89 90 _for(i,1,n+1) 91 _for(j,1,m+1) 92 { 93 a[i][j] = read(); 94 zong += a[i][j]; 95 if((i+j)%2) 96 { 97 add(s,getHash(i,j),a[i][j]),add(getHash(i,j),s,0); 98 if(i > 1) {add(getHash(i,j),getHash(i-1,j),INF);add(getHash(i-1,j),getHash(i,j),0);} 99 if(i < n) {add(getHash(i,j),getHash(i+1,j),INF);add(getHash(i+1,j),getHash(i,j),0);} 100 if(j > 1) {add(getHash(i,j),getHash(i,j-1),INF);add(getHash(i,j-1),getHash(i,j),0);} 101 if(j < m) {add(getHash(i,j),getHash(i,j+1),INF);add(getHash(i,j+1),getHash(i,j),0);} 102 } 103 else 104 {add(getHash(i,j),t,a[i][j]);add(t,getHash(i,j),0);} 105 } 106 107 int flow = 0; 108 while(bfs()) 109 while(flow = dinic(s,INF)) 110 maxflow += flow; 111 112 write(zong-maxflow); 113 return 0; 114 }