TYVJ1338 QQ农场

时间: 1000ms / 空间: 131072KiB / Java类名: Main

背景

Sandytea前段时间沉迷于QQ农场中……一天夜里,他梦见来到好友X的农场上……

描述

这个农场和游戏中略有不同。土地实际上是一个边长为N的正方形,由N*N块土地组成。
在每块土地上,都种有一种农作物。如果他选择摘取一块土地上的农作物,就能获得一个固定的利润(当然,这个利润是正数)。不同土地上的利润多半是不同的。
贪心的Sandytea本想摘取所有土地上的农作物。但是正当他准备行动时,却被告知不允许摘取了两块有公共边的土地上的作物,否则就会被主人的狗发现。
Sandytea想知道,在不被狗抓住的前提下,他能获得的最大利益是多少。

输入格式

第一行:一个整数N,表示土地是一个边长为N的正方形。
下面N行:每行N个正整数,描述了各块土地上的农作物的单位价值。

输出格式

输出一行,包含一个整数,为最大的收益。

测试样例1

输入


7 7 
54 54

输出

61

备注

数据范围:
有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 }
原文地址:https://www.cnblogs.com/SilverNebula/p/6240193.html