题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1565
方格取数(1)
Problem Description
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
Input
包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20)
Output
对于每个测试实例,输出可能取得的最大的和
Sample Input
3 75 15 21 75 15 28 34 70 5
Sample Output
188
这道题我是不会的,所以解释不了,这里的代码是别人做出来的。之所以不是我自己做的也贴出来,是因为我觉得至少我是看过这个题,也思考过,只不过暂时还没想通而已,嘿嘿...还希望有朋友懂的话能写个详细一点的解题报告和我分享一下!
代码:
#include <iostream>
#include <iostream>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
#define NODE_MAX 500
#define INF 0x3f3f3f3f
#define min(a,b) (a)<(b)?(a):(b)
int node_num;
int tu[NODE_MAX][NODE_MAX];
int SAP(int sta,int ed)
{
int dist[NODE_MAX],path[NODE_MAX],num[NODE_MAX];
memset(dist,0,sizeof(dist));
memset(num,0,sizeof(num));
memset(path,0,sizeof(path));
int maxflow=0;
int now=sta;
while( dist[sta]<=node_num )
{
int m=INF,k;
for(int i=1;i<=node_num;i++)
{
if( tu[now][i]>0 && m>dist[i]+1 )
{
k=i;
m=dist[i]+1;
}
}
if(m==INF)
m=node_num+2;
if(m==dist[now])
{
path[k]=now;
now=k;
if(now==ed)
{
int minn=INF;
while(k!=sta)
{
minn = min(minn,tu[path[k]][k]);
k=path[k];
}
k=now;
while(k!=sta)
{
tu[path[k]][k]-=minn;
tu[k][path[k]]+=minn;
k=path[k];
}
maxflow+=minn;
memset(path,0,sizeof(path));
now=sta;
}
}
else
{
++num[m];
--num[dist[now]];
if( num[dist[now]]==0 )
return maxflow;
dist[now] = m;
if( now!=sta )
now=path[now];
}
}
return maxflow;
}
int gra[25][25],col[25][25];
int main()
{
int n;
while(scanf("%d",&n)==1)
{
memset(gra,0,sizeof(gra));
memset(col,0,sizeof(col));
memset(tu,0,sizeof(tu));
int sum=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&gra[i][j]);
sum+=gra[i][j];
}
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
if(j==1)
col[i][j] =! col[i-1][j];
else
col[i][j] =! col[i][j-1];
if( col[i][j] )
{
tu[1][i*n+j+1] = gra[i][j];
if(i>1)
tu[i*n+j+1][(i-1)*n+j+1]=INF;
if(i<n)
tu[i*n+j+1][(i+1)*n+j+1]=INF;
if(j<n)
tu[i*n+j+1][i*n+j+1+1]=INF;
if(j>1)
tu[i*n+j+1][i*n+j-1+1]=INF;
}
else
tu[i*n+j+1][n*n+n+4] = gra[i][j];
}
}
node_num = n*n+4+n;
printf("%d\n",sum-SAP(1,n*n+4+n));
}
return 0;
}