二分图匹配 hrbust 1697 国际象棋
一个骑士控制两个格子 最少的骑士控制棋盘上的每一个格子。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define clr(x) memset(x,0,sizeof(x))
struct node
{
int to,next;
}q[300000];
int head[40*10+100];
int tot;
void add(int s,int u)
{
q[tot].to=u;
q[tot].next=head[s];
head[s]=tot++;
}
int l[10000];
int v[10000];
int find(int x)
{
int k,i;
for(i=head[x];i;i=q[i].next)
{
k=q[i].to;
if(!v[k])
{
v[k]=1;
if(l[k]==0||find(l[k]))
{
l[k]=x;
return 1;
}
}
}
return 0;
}
int g[50][50];
int num[50][50];
long long sum;
int main()
{
int f,n,m,i,j,p,pp;
while( scanf("%d",&n)!=EOF)
{
clr(head);
clr(g);
clr(num);
clr(l);
tot=1;
sum=0;
int k=0;
while(scanf("%d%d",&p,&pp))
{
if(pp==0&&p==0)break;
p--;pp--;
g[p][pp]=1;
k++;
}
int number=0;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(!g[i][j])num[i][j]=number++;
}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(g[i][j]==0)
{
if(i+1<n&&j+2<n&&g[i+1][j+2]==0)add(num[i][j],num[i+1][j+2]);
if(j+1<n&&i+2<n&&g[i+2][j+1]==0)add(num[i][j],num[i+2][j+1]);
if(i+1<n&&j-2>=0&&g[i+1][j-2]==0)add(num[i][j],num[i+1][j-2]);
if(i+2<n&&j-1>=0&&g[i+2][j-1]==0)add(num[i][j],num[i+2][j-1]);
if(i-1>=0&&j+2<n&&g[i-1][j+2]==0)add(num[i][j],num[i-1][j+2]);
if(i-2>=0&&j+1<n&&g[i-2][j+1]==0)add(num[i][j],num[i-2][j+1]);
if(i-1>=0&&j-2>=0&&g[i-1][j-2]==0)add(num[i][j],num[i-1][j-2]);
if(i-2>=0&&j-1>=0&&g[i-2][j-1]==0)add(num[i][j],num[i-2][j-1]);
}
n=n*n-k;
for(i=0;i<n;i++)
{
clr(v);
if(find(i))sum++;
}
printf("%lld\n",n-sum/2);
}
return 0;
}
hrbust1697 国际象棋
最新推荐文章于 2019-08-25 12:05:00 发布