棋盘覆盖
(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; }