[TYVJ1338] QQ农场
Posted lh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[TYVJ1338] QQ农场相关的知识,希望对你有一定的参考价值。
描述
这个农场和游戏中略有不同。土地实际上是一个边长为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。
有10分的数据满足:N≤6
另有20分的数据满足:N≤13
另有30分的数据满足:N≤50
另有40分的数据满足:N≤200
所有数据满足:每块土地上作物的价值不超过100。
最小割:最大化利益=最小化损失
把网格黑白染色,
把网格黑白染色,
由源点向黑格连容量为格点权值的边,白格向汇点连容量为格点权值的边,每个黑格子向相邻的格子连容量为inf的边
把黑格子割到源点表示采摘该格作物,否则不采摘
把白格子割到汇点表示采摘该格作物,否则不采摘
为什么相邻格子要连INF的边呢?
题目说,不能采相邻格子的作物,而如果连INF的边,就说明这条边必不可能被割断,相邻格子就必不可能都能被采摘(否则S到T连通)
注意,必须从黑格(即为与源点连边的格子)向白格(即为与汇点连边的格子)连边
不能从白格向黑格连边或黑白格互相连边(即从黑格向白格连边,白格也向黑格连边)
为什么呢?
如果互相连边,那么下图1,3两个点就变相有了限制关系,而事实上并不是取了1号点就不能取3号点(1号点只与2号点相邻)
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int INF=1999999999; int h[1000000],next[1000000],cap[1000000],to[1000000],k=1; int level[40100],que[40100],head,tail,iter[40100],n; int x[4]={-1,0,1,0},y[4]={0,-1,0,1}; void ins(int u,int v,int c){next[++k]=h[u];h[u]=k;to[k]=v;cap[k]=c;} int get(int i,int j){return (i-1)*n+j;} bool bfs(int S,int T) { memset(level,0,sizeof(level)); head=tail=0;que[tail++]=S;level[S]=1; while(head<tail) { int u=que[head++]; for(int i=h[u];i;i=next[i]) { int v=to[i]; if(!level[v]&&cap[i]) { level[v]=level[u]+1;que[tail++]=v; } } } if(!level[T])return 0;return 1; } int dfs(int u,int T,int f) { if(u==T)return f; int used=0; for(int &i=iter[u];i;i=next[i]) { int v=to[i]; if(level[v]==level[u]+1&&cap[i]) { int w=dfs(v,T,min(cap[i],f-used));used+=w; if(w) { cap[i]-=w;cap[i^1]+=w;if(f==used)return f; } } } return used; } int dinic(int S,int T) { int flow=0; while(1) { for(int i=0;i<=n*n+1;i++)iter[i]=h[i]; if(!bfs(S,T))return flow;flow+=dfs(S,T,INF); } } int main() { scanf("%d",&n);int S=0,T=n*n+1,tot=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { int v;scanf("%d",&v);tot+=v; if(i%2==j%2){ins(get(i,j),T,v);ins(T,get(i,j),0);} else { for(int k=0;k<4;k++) { int ii=i+x[k],jj=j+y[k];if(ii<1||ii>n||jj<1||jj>n)continue; ins(get(i,j),get(ii,jj),INF);ins(get(ii,jj),get(i,j),0); } ins(S,get(i,j),v);ins(get(i,j),S,0); } } cout<<tot-dinic(S,T); return 0; }
以上是关于[TYVJ1338] QQ农场的主要内容,如果未能解决你的问题,请参考以下文章