读完题发现拐角处一定放在 为奇数的地方
所以可以想办法转化为 (因为要减去最多嘛)
然后就有一些性质了
当确定某个格子 作为拐角放置
为了构成 形状,还需要覆盖 个格子
可以是上左,上右,下左,下右
但这样不够
所以至此就把点分成了 类
的构成可以看作从奇数列的偶数格子出发经过拐点到达偶数列的偶数格子
这样就可以构成一个三分图(也可以说四分图,因为拐点要被拆点了)
(无特别说明,流量都是1,费用都是0)
#include <bits/stdc++.h>
using namespace std;
const int maxn=50009;
const int inf=1e9;
#define id(x,y) (x-1)*n+y
int a[509][509];
int n,m,s,t,k;
int maxflow,mincost;
int dis[maxn],head[maxn<<1],cnt=1,flow[maxn],pre[maxn],vis[maxn];
struct edge{
int to,nxt,w,flow;//分别代表
}d[maxn<<1];
void add(int u,int v,int flow,int w)//最大流量,单位费用
{
d[++cnt]=(edge){v,head[u],w,flow},head[u]=cnt;
d[++cnt]=(edge){u,head[v],-w,0},head[v]=cnt;
}
bool spfa()
{
queue<int>q;
for(int i=0;i<=t;i++) dis[i]=inf;
memset(vis,0,sizeof(vis));
q.push(s);
dis[s]=0,vis[s]=1;
flow[s] = inf;//初始流量无限大
while( !q.empty() )
{
int u=q.front(); q.pop();
vis[u]=0;//出队
for(int i=head[u];i;i=d[i].nxt)
{
if( !d[i].flow ) continue;//无流量了
int v=d[i].to;
if( dis[v]>dis[u]+d[i].w )
{
dis[v]=dis[u]+d[i].w;
flow[v] = min(flow[u],d[i].flow);//更新当前流量
pre[v]=i;//记录从哪条边过来的
if( !vis[v] ) vis[v]=1,q.push(v);
}
}
}
if( dis[t]==inf ) return 0;
return 1;
}
int x[5]={0,0,1,-1},y[5]={1,-1,0,0};
int main()
{
cin >> n >> m >> k;
int sumn=0;
s=0,t=n*n*2+1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin >> a[i][j],sumn+=a[i][j];
for(int i=1;i<=k;i++)
{
int l,r; cin >> l >> r;
a[l][r]=-1;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if( a[i][j]==-1 ) continue;
if( (i+j)%2 )//奇数格子
add( id(i,j),id(i,j)+n*n,1,-a[i][j] );
else//偶数格子
{
if( j%2==1 )//奇数列
{
add(s,id(i,j),1,0);
for(int q=0;q<4;q++)
{
int nx=i+x[q],ny=j+y[q];
if( nx<1||nx>n||ny<1||ny>n ) continue;
if( a[nx][ny]==-1 ) continue;
add(id(i,j),id(nx,ny),1,0);
}
}
else
{
add(id(i,j),t,1,0);
for(int q=0;q<4;q++)
{
int nx=i+x[q],ny=j+y[q];
if( nx<1||nx>n||ny<1||ny>n ) continue;
if( a[nx][ny]==-1 ) continue;
add(id(nx,ny)+n*n,id(i,j),1,0);
}
}
}
}
while( spfa()&&m )
{
if( dis[t]>0 ) break;
int i,x=t;
while( x!=s )
{
i=pre[x];
d[i].flow-=flow[t],d[i^1].flow+=flow[t];
x=d[i^1].to;
}
m-=flow[t];
mincost+=dis[t]*flow[t];
}
cout << sumn+mincost;
}