棋盘覆盖

http://www.tyvj.cn/

 

(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;
}
    

 

 

 

posted @ 2010-11-08 07:40  forever zsz  阅读(548)  评论(1编辑  收藏  举报