思路:和之前的建立网络战的题目类似,就是通过当前的合要求的点开始向四周寻找,若四周有合格的便将他们建立关系。注意其中的边界处理
#include<iostream> #include<cstring> #include<queue> #include<cstdio> #define inf 0x3f3f3f3f using namespace std; int Map[2000][2000],cropath[6000],id[2000][2000],head[2000]; bool use[6000],vis[2000][2000]; int n,m,z; struct node { int to,next; } q[10000]; int cnt; void creat(int a,int b) { q[z].to=b; q[z].next=head[a]; head[a]=z++; } int DFS(int v) { int i,k; for(i=head[v]; i!=-1; i=q[i].next) { k=q[i].to;//看的是当前的顶点是否被用 if(!use[k]) { use[k]=true; if(cropath[k]==-1||DFS(cropath[k])) { cropath[k]=v; return 1; } } } return 0; } int main() { int a,b,n,m,i,j,k; while(~scanf("%d%d%d",&m,&n,&k)) { z=0; memset(head,-1,sizeof(head)); memset(cropath,-1,sizeof(cropath)); memset(vis,false,sizeof(vis)); for(i=0; i<k; i++) { scanf("%d%d",&a,&b); vis[b][a]=true; } if(((n*m)-k)&1) { printf("NO\n"); continue; } cnt=0; for(i=1; i<=m; i++) for(j=1; j<=n; j++) if(!vis[i][j])//统计有多少正常的格子 id[i][j]=cnt++; for(i=1; i<=m; i++) for(j=1; j<=n; j++) if(!vis[i][j]) { if(i-1>0&&!vis[i-1][j])//注意边界 creat(id[i][j],id[i-1][j]); if(j-1>0&&!vis[i][j-1]) creat(id[i][j],id[i][j-1]); if(i+1<=m&&!vis[i+1][j]) creat(id[i][j],id[i+1][j]); if(j+1<=n&&!vis[i][j+1]) creat(id[i][j],id[i][j+1]); } int ans=0; for(i=0; i<cnt; i++) { memset(use,false,sizeof(use)); if(DFS(i)) ans++; } //cout<<ans<<endl; if(ans==cnt) printf("YES\n"); else printf("NO\n"); } return 0; }