POJ2446

来源:互联网 发布:淘宝售前客服用语 编辑:程序博客网 时间:2024/05/18 01:42

Problem: Chessboard
Description: 拿一张12规格的卡片来覆盖一个矩阵,这个举证上面有些洞,这些洞是不能覆盖的,现在问你这项任务能不能完成。
Solution: 一看这个问题我一开始想用bfs。但是这个题目是归到了二分图的最大匹配里面,然后仔细一想就知道了,我们可以通过这个卡片来体现匹配的意思,一张卡片要覆盖两个格子嘛,现在所有的格子都要被覆盖,那么也就是说,这些格子都能匹配上另一个格子,这里建图的时候最好画一个图形来体现二分图的最大匹配,不然很容易想错的。我一开始就想错了。建好图后就是匈牙利算法了,如果匹配数等于格子数,那么这项任务就能完成。
Code(C++):

#include <iostream>#include <vector>#include <string.h>#include <math.h>using namespace std;const int M=32*32+500;const int dirx[]={0,0,1,-1};const int diry[]={1,-1,0,0};bool used[M];int belong[M];int map[M][M];int n,m;int R,C,num;vector<int> to[M];bool dfs(int s){    for(int i=0;i<to[s].size();i++){        int end=to[s].at(i);        if(used[end])            continue;        used[end]=true;        if(belong[end]==-1||dfs(belong[end])){            belong[end]=s;            return true;        }    }    return false;}int main(){    while(cin>>R>>C>>num){        n=m=0;        for(int i=0;i<M;i++)            to[i].clear(),            belong[i]=-1;        memset(map,0,sizeof(map));        for(int i=1;i<=num;i++){            int x,y;            cin>>y>>x;            map[x][y]=-1;        }        if(num%2){            cout<<"NO"<<endl;            continue;        }        for(int i=1;i<=R;i++)            for(int j=1;j<=C;j++)                if(map[i][j]!=-1){                    for(int k=0;k<4;k++){                        int tx=i+dirx[k];                        int ty=j+diry[k];                        if(tx>=1&&tx<=R&&ty>=1&&ty<=C&&                                map[tx][ty]!=-1)                            ++m,                            to[(i-1)*32+j].push_back((tx-1)*32+ty);                    }                    ++n;                }        int ans=0;        for(int i=1;i<=32*32;i++){            memset(used,false,sizeof(used));            if(dfs(i))                ++ans;        }        if(ans==n)            cout<<"YES";        else            cout<<"NO";        cout<<endl;    }    return 0;}
0 0
原创粉丝点击