poj2446Chessboard 奇偶建图

来源:互联网 发布:淘宝上怎么买steam游戏 编辑:程序博客网 时间:2024/06/06 04:05
/*因为要用1*2的纸片覆盖,那么两个值(i+j)必然一个奇数一个偶数,然后分别给图中的奇数偶数点依次从1开始标号,相邻的按其标号建图,匈牙利、、比较快速,正解!因为必然是一个奇数点对应一个相邻偶数点,那么只要求任意奇数或偶数的最大匹配就可以了。经典的建图方法。*/#include<iostream>#include<stdio.h>#include<string.h>using namespace std;#define maxm 4050int n,m,s,tmp,temp;int map[maxm][maxm],vis[maxm],link[maxm];//map存图int dfs(int t){    for(int i=1;i<temp;i++)//i<temp    {        if(vis[i]==0&&map[t][i])        {            vis[i]=1;            if(link[i]==-1||dfs(link[i]))            {                link[i]=t;                return 1;            }        }    }    return 0;}int MaxMatch(){    int num=0;    memset(link,-1,sizeof(link));    for(int i=1;i<tmp;i++)//i<tmp    {        memset(vis,0,sizeof(vis));        if(dfs(i))        num++;    }    return num;}int main(){    int a,b,mmap[40][40];    while(cin>>n>>m>>s)    {memset(map,0,sizeof(map));memset(mmap,0,sizeof(mmap));        tmp=1;temp=1;        for(int i=0; i<s; i++)        {            cin>>a>>b;            mmap[b][a]=-1;///        }        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++){                if(mmap[i][j]!=-1){                    if((i+j)&1) mmap[i][j]=temp++;                    else mmap[i][j]=tmp++;                }            }        for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++){            if(mmap[i][j]!=-1&&((i+j)&1)){                if(mmap[i-1][j]>0) map[mmap[i-1][j]][mmap[i][j]]=1;                if(mmap[i+1][j]>0) map[mmap[i+1][j]][mmap[i][j]]=1;                if(mmap[i][j-1]>0) map[mmap[i][j-1]][mmap[i][j]]=1;                if(mmap[i][j+1]>0) map[mmap[i][j+1]][mmap[i][j]]=1;            }        }        cout<<((n*m-s==2*MaxMatch())?"YES":"NO")<<endl;    }    return 0;}

0 0
原创粉丝点击