[BZOJ1475]方格取数 网络流 最小割
1475: 方格取数
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1025 Solved: 512
[Submit][Status][Discuss]
Description
在一个n*n的方格里,每个格子里都有一个正整数。从中取出若干数,使得任意两个取出的数所在格子没有公共边,且取出的数的总和尽量大。
Input
第一行一个数n;(n<=30) 接下来n行每行n个数描述一个方阵
Output
仅一个数,即最大和
Sample Input
2
1 2
3 5
1 2
3 5
Sample Output
6
黑白染色求最小割
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<cmath> 6 #include<algorithm> 7 using namespace std; 8 int tx[5]={0,1,0,-1}; 9 int ty[5]={1,0,-1,0}; 10 struct data { 11 int to,next,f; 12 }e[800005]; 13 int head[5005],cnt; 14 void add(int u,int v,int f){e[cnt].to=v;e[cnt].next=head[u];e[cnt].f=f;head[u]=cnt++;} 15 int n,m,s,t; 16 bool vis[5005]; 17 int q[5005],dis[5005]; 18 bool bfs() { 19 memset(dis,-57,sizeof(dis)); 20 int h=0,tail=1; 21 q[h]=t; 22 dis[t]=0; 23 while(h!=tail) { 24 int now=q[h++];if(h==5000) h=0; 25 for(int i=head[now];i>=0;i=e[i].next) { 26 if(dis[e[i].to]>-100000||!e[i^1].f) continue; 27 dis[e[i].to]=dis[now]-1; 28 q[tail++]=e[i].to;if(tail==5000) tail=0; 29 } 30 } 31 return dis[s]>=-100000; 32 } 33 int dfs(int now,int a) { 34 int f=0,flow=0; 35 if(now==t) return a; 36 for(int i=head[now];i>=0;i=e[i].next) { 37 int to=e[i].to; 38 if(dis[to]==dis[now]+1&&e[i].f>0) { 39 f=dfs(to,min(a,e[i].f)); 40 flow+=f; 41 e[i].f-=f; 42 e[i^1].f+=f; 43 a-=f; 44 if(a==0) break; 45 } 46 } 47 return flow; 48 } 49 int num=0; 50 int ans=0; 51 int sum=0; 52 void dinic() { 53 while(bfs()) { 54 sum+=dfs(s,2147483647); 55 } 56 printf("%d",num-sum); 57 } 58 int tt=0; 59 int a[50][50]; 60 int main() { 61 memset(head,-1,sizeof(head)); 62 scanf("%d%d",&m,&n); 63 s=0,t=5000; 64 for(int i=1;i<=m;i++) 65 for(int j=1;j<=n;j++) { 66 scanf("%d",&a[i][j]); 67 num+=a[i][j]; 68 } 69 for(int i=1;i<=m;i++) { 70 for(int j=1;j<=n;j++) { 71 if((i+j)&1) { 72 add(s,(i-1)*n+j,a[i][j]),add((i-1)*n+j,s,0); 73 for(int k=0;k<=3;k++) { 74 int tox=i+tx[k],toy=j+ty[k]; 75 if(tox==0||tox>m||toy==0||toy>n) continue; 76 add((i-1)*n+j,(tox-1)*n+toy,1e8); 77 add((tox-1)*n+toy,(i-1)*n+j,0); 78 } 79 } 80 else add((i-1)*n+j,t,a[i][j]),add(t,(i-1)*n+j,0); 81 82 } 83 } 84 dinic(); 85 }
O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~