POJ 2446

来源:互联网 发布:java jdk1.7 32位下载 编辑:程序博客网 时间:2024/06/12 00:19

题目大意:

给定一个M*N大小的棋盘,其中的一些点是洞,无法放置卡片,卡片是占两个格子的矩形方块。现在用程序来判断 是否可以用卡片不重叠的 将整个棋盘填满?


思路:

看到这道题,压根刚开始没想起来用二分图,最大匹配来做。后来看了网上的博客,才有些思路。 首先要明确的是,在棋盘中,[i,j]表示的点如果i+j为偶数,那么周围的四个点的横纵坐标之和一定为奇数,反过来也一样。那么我们就可以将 奇数表示的点 放在一个集合里,偶数表示的点 放在另一个集合里。 最后,求这个图的最大匹配。

如果ans * 2 等于格子数减去洞的数量,那么就输出 YES,否则输出NO。 因为每条边 占 两格,所以ans 要乘以2

本题的关键还是建图,的确刚开始比较难想到。还有比较关键的是,如果从偶数的集合里面开始寻找增广路的话,那么在map数组赋值为1 时,要使每个偶数点指向奇数点,也就是说,不仅要 path[i][j]不等于1,而且(i+j)%2 == 1,这里是一个注意点 ; 当然你从奇数的集合里面开始的话,使每个奇数点指向偶数点 也是可以的。

#include <iostream>using namespace std;#define MAX 35int map[MAX*MAX][MAX*MAX];bool visit[MAX*MAX];int check[MAX*MAX];int m,n,k,temp1,temp2;bool dfs(int v){    for(int i=1;i<temp2;i++){        if(!visit[i]&&map[v][i]){            visit[i] = 1;            if(check[i] == -1 || dfs(check[i])){                check[i] = v;                return true;            }        }    }    return false;}void hungry(){    int ans = 0;    memset(check,-1,sizeof(check));    for(int i=1;i<temp1;i++){        memset(visit,0,sizeof(visit));        if(dfs(i))            ans++;    }    if((ans*2)==(m*n-k))        cout<<"YES"<<endl;    else        cout<<"NO"<<endl;}int main(){    int i,j,a,b;    scanf("%d %d %d",&m,&n,&k);    int path[MAX][MAX];    memset(path,0,sizeof(path));    for(i=0;i<k;i++){        scanf("%d %d",&a,&b);        path[b][a] = -1;    }    temp1 = 1;    temp2 = 1;    for(i=1;i<=m;i++){        for(j=1;j<=n;j++){            if(path[i][j]==0){                if((i+j)%2==0)                    path[i][j] = temp1++;                else                    path[i][j] = temp2++;            }        }    }    memset(map,0,sizeof(map));    for(i=1;i<=m;i++){        for(j=1;j<=n;j++){            if(path[i][j]!=-1 && (i+j)%2 == 1){                if(path[i-1][j]>=1)                    map[path[i-1][j]][path[i][j]] = 1;                if(path[i+1][j]>=1)                    map[path[i+1][j]][path[i][j]] = 1;                if(path[i][j-1]>=1)                    map[path[i][j-1]][path[i][j]] = 1;                if(path[i][j+1]>=1)                    map[path[i][j+1]][path[i][j]] = 1;            }        }    }    hungry();    return 0;}



0 0
原创粉丝点击