poj2446 Chessboard

来源:互联网 发布:人工智能电影剧情详细 编辑:程序博客网 时间:2024/05/16 06:52
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int MaxN=2000;int N,M,row,col,k;int Ans;int link[MaxN];//记录点匹配的点的编号bool cover[MaxN];//记录点是否被搜索过bool Map[MaxN][MaxN];//邻接矩阵 true代表有边相连int num[MaxN][MaxN];int id[MaxN][MaxN];void build(){int i,j,temp;N=0;M=0;memset(id,0,sizeof(id));for (i=1;i<=row;i++){if (i%2==0)j=2;elsej=1;for (;j<=col;j+=2){if (num[i][j]!=-1){N++;id[i][j]=N;}}}for (i=1;i<=row;i++){if (i%2==0)j=1;else j=2;for (;j<=col;j+=2){if (num[i][j]!=-1){M++;id[i][j]=M;if (i>1 && num[i-1][j]!=-1)Map[id[i-1][j]][M]=1;if (i<row && num[i+1][j]!=-1)Map[id[i+1][j]][M]=1;if (j>1 && num[i][j-1]!=-1)Map[id[i][j-1]][M]=1;if (j<col && num[i][j+1]!=-1)Map[id[i][j+1]][M]=1;}}}}bool Find(int i){    int j;    for(j=1;j<=M;++j)        if(Map[i][j] && !cover[j])//如果结点i与j相邻并且未被查找过        {            cover[j]=true;//标记j为已经查找过            if(!link[j]//如果j未在前一个匹配M中|| Find(link[j]))//j在匹配M中,但是从与j相邻的结点出发可以有增广路            {                link[j]=i;//记录查找成功记录                return true;//返回查找成功            }        }return false;}void solve(){    int i;    memset(link,0,sizeof(link));    for(i=1;i<=N;++i){        memset(cover,false,sizeof(cover));//清空上次搜索时的标记        if (Find(i))//从节点i尝试扩展Ans++;    }}void out(){    if (Ans==(row*col-k)/2)printf("YES\n");else printf("NO\n");}int main(){int i,x,y;while (scanf("%d%d%d",&row,&col,&k)!=EOF){if ((row*col-k)%2==1){printf("NO\n");continue;}Ans=0;memset(Map,false,sizeof(Map));memset(num,0,sizeof(num));for (i=1;i<=k;i++){scanf("%d%d",&x,&y);num[y][x]=-1;}build();solve();out();}    return 0;}


原创粉丝点击