1475: 方格取数
Description
在一个n*n的方格里,每个格子里都有一个正整数。从中取出若干数,使得任意两个取出的数所在格子没有公共边,且取出的数的总和尽量大。
Input
第一行一个数n;(n<=30) 接下来n行每行n个数描述一个方阵
Output
仅一个数,即最大和
Sample Input
2
1 2
3 5
Sample Output
6
【解题报告】
代码如下:
/**************************************************************
Problem: 1475
User: onepointo
Language: C++
Result: Accepted
Time:124 ms
Memory:2164 kb
****************************************************************/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
#define N 10010
#define M 100010
int cnt=-1,head[N];
struct Edge{int to,nxt,f;}e[M];
int vis[N],dis[N];
int n,m,ss,tt;
int mp[50][50],ans=0,mark[50][50];
int xx[4]={0,0,1,-1},yy[4]={1,-1,0,0};
void adde(int u,int v,int c)
{
e[++cnt].to=v;e[cnt].f=c;
e[cnt].nxt=head[u];head[u]=cnt;
e[++cnt].to=u;e[cnt].f=0;
e[cnt].nxt=head[v];head[v]=cnt;
}
bool bfs()
{
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
queue <int> q;
vis[ss]=1;q.push(ss);
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=head[u];~i;i=e[i].nxt)
{
int v=e[i].to;
if(e[i].f&&!vis[v])
{
q.push(v);vis[v]=1;
dis[v]=dis[u]+1;
}
}
}
return vis[tt];
}
int dfs(int u,int delta)
{
if(u==tt) return delta;
int ret=0;
for(int i=head[u];delta&&~i;i=e[i].nxt)
{
int v=e[i].to;
if(e[i].f&&dis[v]==dis[u]+1)
{
int flow=dfs(v,min(e[i].f,delta));
e[i].f-=flow;
e[i^1].f+=flow;
delta-=flow;
ret+=flow;
}
}
return ret;
}
int Dinic()
{
int ret=0;
while(bfs()) ret+=dfs(ss,inf);
return ret;
}
bool pd(int x,int y)
{
if(x<1||y<1||x>n||y>n) return 0;
return 1;
}
int main()
{
// freopen("in","r",stdin);
memset(head,-1,sizeof(head));
scanf("%d",&n);
ss=0,tt=n*n+1;
int w=(n*n+1)/2,b=0;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
{
if((i+j)%2==0) b++,mark[i][j]=b;
else w++,mark[i][j]=w;
scanf("%d",&mp[i][j]);
ans+=mp[i][j];
}
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
{
if((i+j)%2==0)
{
adde(0,mark[i][j],mp[i][j]);
for(int k=0;k<4;k++)
if(pd(i+xx[k],j+yy[k]))
adde(mark[i][j],mark[i+xx[k]][j+yy[k]],inf);
}
else adde(mark[i][j],tt,mp[i][j]);
}
printf("%d",ans-Dinic());
return 0;
}