最大点权独立集->最小点权覆盖集->最小割->最大流~
果然细节最多的还是网络流~~~
#include<iostream>
#include<queue>
#include<vector>
#include<iomanip>
#include<string>
#include<algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
const int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
const int maxn = 55;
const int maxc = 555;
vector<int> g[maxc];
int f[maxc][maxc];
int c[maxc][maxc];
bool you[maxc][maxc];
int cen[maxc];
int n,total;
int a[maxn][maxn];
queue<int>q;
int dx(int index)
{
return (index-1)/n + 1;
}
int dy(int index)
{
return (index % n) ? index % n : n;
}
int num(int x,int y)
{
return (x-1)*n+y;
}
bool yes(int x,int y)
{
if(x>=1 && x<=n && y>=1 && y<=n)
{
return true;
}
return false;
}
void init()
{
memset(you,false,sizeof(you));
memset(f,0,sizeof(f));
memset(c,0,sizeof(c));
for(int i=0;i<=n*n+1;i++)
{
g[i].clear();
}
return ;
}
bool bfs()
{
while(!q.empty())
{
q.pop();
}
memset(cen,-1,sizeof(cen));
q.push(0);
cen[0]=0;
int now,to;
while(!q.empty())
{
now = q.front();
q.pop();
for(int i=0;i<g[now].size();i++)
{
to = g[now][i];
if(! you[now][to] || cen[to]!=-1 )
{
continue;
}
cen[to]=cen[now] + 1;
q.push(to);
}
}
if(cen[n*n+1] == -1)
{
return false;
}
else
{
return true;
}
}
int dfs(int now = 0,int flow = inf)
{
if(cen[now] == cen[n*n+1])
{
if(now == n*n+1)
{
return flow;
}
else
{
return 0;
}
}
int temp,sum;
sum=0;
for(int i=0;i<g[now].size();i++)
{
if(!you[now][g[now][i]] || cen[g[now][i]] - cen[now] != 1 )
{
continue;
}
temp = dfs(g[now][i] , min ( flow , c[now][g[now][i]] - f[now][g[now][i]] ) );
f[now][g[now][i]] += temp;
f[g[now][i]][now] -= temp;
sum += temp;
flow -= temp;
if(f[now][g[now][i]] == c[now][g[now][i]] )
{
you[now][g[now][i]] = false;
}
you[g[now][i]][now] = true;
}
return sum;
}
int dinic()
{
int ans = 0;
while( bfs() )
{
ans += dfs();
}
return ans;
}
int main()
{
while(cin>>n)
{
init();
total=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
total += a[i][j];
}
}
int tx,ty;
for(int i=1;i<=n*n;i++)
{
if( (dx(i)+dy(i))%2 == 0 )
{
you[0][i] = true;
c[0][i] = a[dx(i)][dy(i)];
g[0].push_back(i);
g[i].push_back(0);
for(int j=0;j<4;j++)
{
tx = dx(i) + dir[j][0];
ty = dy(i) + dir[j][1];
if(!yes(tx,ty)) continue;
c[i][num(tx,ty)]=inf;
you[i][num(tx,ty)] = true;
g[i].push_back(num(tx,ty));
g[num(tx,ty)].push_back(i);
}
}
else
{
c[i][n*n + 1] = a[dx(i)][dy(i)];
you[i][n*n + 1] =true;
g[n*n + 1].push_back(i);
g[i].push_back(n*n+1);
}
}
cout<<total - dinic()<<endl;
}
return 0;
}