#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<memory.h>
#include<queue>
#include<stack>
using namespace std;
#define N 30
#define INF 0x3fffffff
int map[N][N];
int dis[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int temp[N*N][N*N];
int pre[N*N];
int n;
void clear()
{
memset(map,0,sizeof(map));
memset(temp,0,sizeof(temp));
}
int Judge(int x,int y)// 判断是否越界
{
if(x>0 && x<=n && y>0 && y<=n)
return 1;
return 0;
}
int bfs(int s,int e)
{
int flow=0;
int i;
int min=INF;//找出最小流量
while(1)
{
memset(pre,-1,sizeof(pre));
queue<int> q;//放进去的代表是第几个
q.push(s);
int start;
while(!q.empty())
{
start=q.front();
q.pop();
for(i=1;i<=n*n+1;i++)
{
if(temp[start][i]!=0 && pre[i]==-1)
{
q.push(i);
if(temp[start][i]<min)
min=temp[start][i];
pre[i]=start;
}
}
if(pre[e]!=-1)
break;
}
int u=e;
if(pre[u]<=0)
break;
while(u!=s) // 减去流量
{
temp[pre[u]][u]-=min;
temp[u][pre[u]]+=min;
u=pre[u];
}
flow+=min;
}
return flow;
}
int main()
{
int i,j,sum,s,e;
while(cin>>n)
{
sum=0;
clear();
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
cin>>map[i][j];
sum+=map[i][j];
}
}// 0作为源点 n*n+1作为汇点
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if((i+j)%2==0)
temp[0][(i-1)*n+j]=map[i][j];
else
temp[(i-1)*n+j][n*n+1]=map[i][j];
}
} // 将与源点相连的点的相邻的值附上INF
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
for(int k=0;k<4;k++)
{
int dx=dis[k][0]+i;
int dy=dis[k][1]+j;
if(Judge(dx,dy) && (i+j)%2==0)
{
temp[(i-1)*n+j][(dx-1)*n+dy]=INF;// (i-1)*n+j 代表的是第几个
}
}
}
}
s=0;//源点
e=n*n+1;//汇点
cout<<sum-bfs(s,e)<<endl;
}
return 0;
}
HDU1565 方格取数(1)网络流
最新推荐文章于 2020-06-14 08:20:02 发布