- 首页 > it技术 > >
【luogu 3355】骑士共存问题
【【luogu 3355】骑士共存问题】题目描述
在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。
文章图片
棋盘上某些方格设置了障碍,骑士不得进入
对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑士,使得它们彼此互不攻击
输入格式:
第一行有 2 个正整数n 和 m (1<=n<=200, 0<=m
#include
#include
#include
#include
#define S 40003
#define T 40002
using namespace std;
struct node{
int to,next,flow,from;
}ed[1000100];
int head[41000],deep[41000],size=-1,ind[210][210],curr[41000],max_flow,n,m,k;
int dx[]={1,1,-1,-1,2,2,-2,-2};
int dy[]={2,-2,2,-2,1,-1,1,-1};
int vis[210][210];
void add(int from,int to,int flow)
{
size++;
ed[size].to=to;
ed[size].from=from;
ed[size].flow=flow;
ed[size].next=head[from];
head[from]=size;
}
bool bfs()
{
queue q;
memset(deep,0,sizeof(deep));
q.push(S);
deep[S]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
if(u==T) return true;
for(int i=head[u];
~i;
i=ed[i].next)
{
int v=ed[i].to;
if(!deep[v]&&ed[i].flow)
{
q.push(v);
deep[v]=deep[u]+1;
}
}
}
return false;
}
int dfs(int u,int cur)
{
int rest=cur;
if(u==T) return cur;
for(int i=curr[u];
~i;
i=ed[i].next)
{
int v=ed[i].to;
if(deep[v]==deep[u]+1&&ed[i].flow)
{
int new_flow=dfs(v,min(rest,ed[i].flow));
ed[i].flow-=new_flow;
ed[i^1].flow+=new_flow;
rest-=new_flow;
if(ed[i].flow) curr[u]=i;
if(!rest) break;
}
}
if(cur==rest) deep[u]=-1;
return cur-rest;
}
int dinic()
{
while(bfs())
{
for(int i=0;
i<=40010;
i++) curr[i]=head[i];
max_flow+=dfs(S,1e9);
}
return max_flow;
}
int main()
{
memset(head,-1,sizeof(head));
int cnt=0;
scanf("%d%d",&n,&m);
for(int i=1;
i<=n;
i++)
for(int j=1;
j<=n;
j++)
ind[i][j]=++cnt;
for(int i=1;
i<=m;
i++)
{
int x,y;
scanf("%d%d",&x,&y);
vis[x][y]=1;
}
for(int x=1;
x<=n;
x++)
{
for(int y=1;
y<=n;
y++)
{
if(vis[x][y]) continue;
if(((x+y)%2)==0)
{
for(int k=0;
k<8;
k++)
{
int tx=x+dx[k];
int ty=y+dy[k];
if(tx<1||tx>n||ty<1||ty>n) continue;
add(ind[x][y],ind[tx][ty],1e9);
add(ind[tx][ty],ind[x][y],0);
}
}
}
}
for(int i=1;
i<=n;
i++)
for(int j=1;
j<=n;
j++)
{
if(vis[i][j]) continue;
if(((i+j)%2)==0) add(S,ind[i][j],1),add(ind[i][j],S,0);
else add(ind[i][j],T,1),add(T,ind[i][j],0);
}
printf("%d",n*n-dinic()-m);
return 0;
}
推荐阅读