时间: 1000ms / 空间: 131072KiB / Java类名: Main
背景
Sandytea前段时间沉迷于QQ农场中……一天夜里,他梦见来到好友X的农场上……
描述
这个农场和游戏中略有不同。土地实际上是一个边长为N的正方形,由N*N块土地组成。
在每块土地上,都种有一种农作物。如果他选择摘取一块土地上的农作物,就能获得一个固定的利润(当然,这个利润是正数)。不同土地上的利润多半是不同的。
贪心的Sandytea本想摘取所有土地上的农作物。但是正当他准备行动时,却被告知不允许摘取了两块有公共边的土地上的作物,否则就会被主人的狗发现。
Sandytea想知道,在不被狗抓住的前提下,他能获得的最大利益是多少。
在每块土地上,都种有一种农作物。如果他选择摘取一块土地上的农作物,就能获得一个固定的利润(当然,这个利润是正数)。不同土地上的利润多半是不同的。
贪心的Sandytea本想摘取所有土地上的农作物。但是正当他准备行动时,却被告知不允许摘取了两块有公共边的土地上的作物,否则就会被主人的狗发现。
Sandytea想知道,在不被狗抓住的前提下,他能获得的最大利益是多少。
输入格式
第一行:一个整数N,表示土地是一个边长为N的正方形。
下面N行:每行N个正整数,描述了各块土地上的农作物的单位价值。
下面N行:每行N个正整数,描述了各块土地上的农作物的单位价值。
输出格式
输出一行,包含一个整数,为最大的收益。
测试样例1
输入
2
7 7
54 54
输出
61
备注
数据范围:
有10分的数据满足:N≤6
另有20分的数据满足:N≤13
另有30分的数据满足:N≤50
另有40分的数据满足:N≤200
所有数据满足:每块土地上作物的价值不超过100。改编自SPOJ
有10分的数据满足:N≤6
另有20分的数据满足:N≤13
另有30分的数据满足:N≤50
另有40分的数据满足:N≤200
所有数据满足:每块土地上作物的价值不超过100。改编自SPOJ
网络流最小割
黑白染色后,相邻不同色格子之间连边,答案为总权值减去最小割
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<queue> 8 using namespace std; 9 const int INF=1e9; 10 const int mxn=50100; 11 const int mx[5]={0,1,0,-1,0}; 12 const int my[5]={0,0,1,0,-1}; 13 int read(){ 14 int x=0,f=1;char ch=getchar(); 15 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 16 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 17 return x*f; 18 } 19 struct edge{ 20 int v,nxt,f; 21 }e[mxn*20]; 22 int hd[mxn],mct=1; 23 void add_edge(int u,int v,int c){ 24 e[++mct].v=v;e[mct].f=c;e[mct].nxt=hd[u];hd[u]=mct;return; 25 } 26 void insert(int u,int v,int c){ 27 add_edge(u,v,c);add_edge(v,u,0);return; 28 } 29 int n,m,S,T; 30 int d[mxn]; 31 bool BFS(){ 32 memset(d,0,sizeof d); 33 d[S]=1; 34 queue<int>q; 35 q.push(S); 36 while(!q.empty()){ 37 int u=q.front();q.pop(); 38 for(int i=hd[u];i;i=e[i].nxt){ 39 int v=e[i].v; 40 if(!d[v] && e[i].f){ 41 d[v]=d[u]+1;q.push(v); 42 } 43 } 44 } 45 return d[T]; 46 } 47 int DFS(int u,int lim){ 48 if(u==T)return lim; 49 int tmp,f=0; 50 for(int i=hd[u];i;i=e[i].nxt){ 51 int v=e[i].v; 52 if(d[v]==d[u]+1 && e[i].f){ 53 tmp=DFS(v,min(lim,e[i].f)); 54 e[i].f-=tmp; 55 e[i^1].f+=tmp; 56 lim-=tmp; 57 f+=tmp; 58 if(!lim)return f; 59 } 60 } 61 d[u]=0; 62 return f; 63 } 64 int Dinic(){ 65 int res=0; 66 while(BFS())res+=DFS(S,INF); 67 return res; 68 } 69 int mp[210][210]; 70 int id[210][210],cnt=0; 71 int main(){ 72 int i,j; 73 n=read(); 74 S=0;T=n*n+1; 75 for(i=1;i<=n;i++) 76 for(j=1;j<=n;j++) 77 id[i][j]=++cnt; 78 int smm=0;int nx,ny; 79 for(i=1;i<=n;i++) 80 for(j=1;j<=n;j++){ 81 mp[i][j]=read(); 82 smm+=mp[i][j]; 83 if(((i+j)&1)==0){ 84 insert(S,id[i][j],mp[i][j]); 85 for(int k=1;k<=4;k++){ 86 nx=i+mx[k]; 87 ny=j+my[k]; 88 if(nx || nx<=n || ny || ny<=n){ 89 insert(id[i][j],id[nx][ny],INF); 90 } 91 } 92 } 93 else{ 94 insert(id[i][j],T,mp[i][j]); 95 } 96 } 97 int ans=smm-Dinic(); 98 printf("%d ",ans); 99 return 0; 100 }