1. 程式人生 > >[BZOJ1475]方格取數 網絡流 最小割

[BZOJ1475]方格取數 網絡流 最小割

play closed esc break .com data con 取數 time

1475: 方格取數

Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 1025 Solved: 512
[Submit][Status][Discuss]

Description

在一個n*n的方格裏,每個格子裏都有一個正整數。從中取出若幹數,使得任意兩個取出的數所在格子沒有公共邊,且取出的數的總和盡量大。

Input

第一行一個數n;(n<=30) 接下來n行每行n個數描述一個方陣

Output

僅一個數,即最大和

Sample Input

2
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 }
View Code

[BZOJ1475]方格取數 網絡流 最小割