棋盘覆盖
(p1035)
刚看到的时候想到要用DFS做,可是那数据量太大~~
看完题解发现是一道匹配的题目,具体思路就是把平时的一维的二分图匹配给改成二维的,另外开两个match数组,分别记录横纵坐标.
废话少说,直接看代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
int hh[5]={0,1,-1,0,0},ll[5]={0,0,0,1,-1};
int used[101][101];
bool map[101][101];
int match[101][101],match2[101][101];
int n;
bool dfs(int x,int y)
{
if (x==0||y==0) return 0;
for (int i=1;i<=4;i++)
{
int h,l;
h=hh[i]+x;l=ll[i]+y;
if (h>0&&h<=n&&l>0&&l<=n&&map[h][l]==true)
{
if (used[h][l]==false)
{
used[h][l]=true;
if ((match[h][l]==0&&match2[h][l]==0)||dfs(match[h][l],match2[h][l])==true)
{
match[h][l]=x;
match2[h][l]=y;
return 1;
}
}
}
}
return 0;
}
int main()
{
freopen("zsz.in","r",stdin);
freopen("zsz.out","w",stdout);
int m,x,y;scanf("%d%d",&n,&m);
memset(map,1,sizeof(map));
for (int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
map[x][y]=false;
//map[y][x]=false;
}
int tot=0;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
{
memset(used,0,sizeof(used));
if (map[i][j]==true)
if (dfs(i,j)==true) tot++;
}
printf("%d",tot/2);
return 0;
}