您的位置:首页 > 理论基础 > 计算机网络

网络流二十四题之二十四 —— 骑士共存问题(KNI)

2016-05-14 09:57 846 查看

骑士共存问题

Description

在一个 n∗n 个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。

棋盘上某些方格设置了障碍,骑士不得进入。



对于给定的 n∗n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑士,使得它们彼此互不攻击。

Input

第一行有 2 个正整数 n 和 m(1<=n<=200,0<=m<n2),分别表示棋盘的大小和障碍数。

接下来的 m 行给出障碍的位置。

每行 2 个正整数,表示障碍的方格坐标。

Output

将计算出的共存骑士数输出。

Solution

本题与第九题殊途同归,我就不过多解释了。

建图后,求最小切割,然后将不是障碍的方格个数减去最小切割即可。

Code

[cpp] #include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

#define Min(x,y) ((x)<(y)?(x):(y))
#define PLA(x,y) ((((x)-1)*m)+(y))
#define INF 0x3f3f3f3f
#define ss 0
#define tt 40010

using namespace std;

int m,n,cnt,sum;
bool map[400][400];
int head[41000],nxt[1000010];
int data[1000010],flow[1000010];
int cur[41000];
int dis[41000];
int xx[20]={0,-1,-2,1,2,-1,-2,1,2},
yy[20]={0,-2,-1,2,1,2,1,-2,-1};

queue<int>q;

void add(int x,int y,int z){
nxt[cnt]=head[x];data[cnt]=y;flow[cnt]=z;head[x]=cnt++;
nxt[cnt]=head[y];data[cnt]=x;flow[cnt]=0;head[y]=cnt++;
}

bool BFS(){
memset(dis,-1,sizeof dis);
dis[ss]=0;
q.push(ss);
while(!q.empty()){
int now=q.front();
q.pop();
for(int i=head[now];i!=-1;i=nxt[i]){
if(flow[i]&&dis[data[i]]==-1){
q.push(data[i]);
dis[data[i]]=dis[now]+1;
}
}
}
return dis[tt]>0;
}

int dfs(int now,int low){
if(now==tt)return low;
int Low;
for(int &i=cur[now];i!=-1;i=nxt[i]){
if(flow[i]&&dis[data[i]]==dis[now]+1){
if(Low=dfs(data[i],Min(low,flow[i]))){
flow[i]-=Low;
flow[i^1]+=Low;
return Low;
}
}
}
return 0;
}

int main(){

freopen(”kni.in”,“r”,stdin);
freopen(”kni.out”,“w”,stdout);

memset(head,-1,sizeof head);
scanf(”%d%d”,&m,&n);
for(int i=1;i<=n;i++){
int x,y;
scanf(”%d%d”,&x,&y);
map[x][y]=true;
}
sum=m*m-n;
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)if(!map[i][j]){
if(!((i+j)&1)){
add(ss,PLA(i,j),1);
for(int k=1;k<=8;k++){
int fx=i+xx[k],fy=j+yy[k];
if(fx>=1&&fx<=m&&fy>=1&&fy<=m&&!map[fx][fy])add(PLA(i,j),PLA(fx,fy),INF);
}
}
else
add(PLA(i,j),tt,1);
}
int flag,weight=0;
while(BFS()){
memcpy(cur,head,sizeof head);
while(flag=dfs(ss,INF))weight+=flag;
}
printf(”%d\n”,sum-weight);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: