http://acm.pku.edu.cn/JudgeOnline/problem?id=2446
#include <iostream> #include <vector> using namespace std; #define MAX 1050 vector< vector<int> > map; int mark[MAX]; bool flag[MAX]; int nm,num; int dis[4][2] = {{0,1},{1,0},{-1,0},{0,-1}}; bool dfs(int pos) //搜pos点是否存在增广路 { int i,pre,tp; int len=map[pos].size(); for(i=0;i<len;i++) { tp=map[pos][i]; if(!flag[tp]) { flag[tp]=true; pre=mark[tp]; mark[tp]=pos; if(pre==-1 || dfs(pre)) return true; //如果没被访问过或者存在增广路,pos到该点就存在增广路 mark[tp]=pre; //否则pos到该点就不存在增广路 } } return false; } int main() { int n,m,k,i,j,l,x,y; int graph[35][35]; while (scanf("%d%d%d",&n,&m,&k)!=EOF) { if((n*m-k)%2) { printf("NO/n"); continue; } memset(graph,-1,sizeof(graph)); for(i=1;i<=n;i++) { for (j=1;j<=m;j++) { graph[i][j] = 0; } } for(i=1;i<=k;i++) { scanf("%d%d",&x,&y); graph[y][x] = -1; } num=0; nm=n*m; map.clear(); map.resize(nm+10); memset(mark,-1,sizeof(mark)); for (i=1;i<=n;i++) { for (j=1;j<=m;j++) { if(graph[i][j] == -1) { continue; } for (l=0;l<4;l++) { x = i + dis[l][0]; y = j + dis[l][1]; if(graph[x][y] == 0) map[(i-1)*m+j].push_back((x-1)*m+y); } } } for (i=1;i<=nm;i++) { memset(flag,0,sizeof(flag)); if(dfs(i)) num++; } if(num == (n*m-k)) printf("YES/n"); else printf("NO/n"); } return 0; }