poj 2446(二分匹配) Chessboard

来源:互联网 发布:jenkins 构建php 编辑:程序博客网 时间:2024/05/21 18:48

按照奇偶点建立二分图。

然后,就是二分最大匹配!

 

#include<iostream>#include<cstring>#include<cstdlib>#include<vector>using namespace std;int vis[1500];int match[1500];int map[40][40];int dir[4][2]={ {-1,0},{0,1},{1,0},{0,-1} };int m,n,k;vector<int> nx,ny[1500];bool CanMatch(int px,int py){if(px<1||py<1||px>m||py>n)return 0;if(map[px][py]==3 || map[px][py]==0 )return 1;return 0;}int dfs(int u){for(int i=0;i<ny[u].size();i++){int v=ny[u][i];if( !vis[v] ){vis[v]=1;if( match[v]==-1 || dfs(match[v]) ){match[v]=u;return 1;}}}return 0;}int Hangary(){int res=0;memset(match,-1,sizeof(match));for(int i=0;i<nx.size();i++){int u=nx[i];memset(vis,0,sizeof(vis));res+=dfs(u);}return res;}int main(){while(scanf("%d %d %d",&m,&n,&k)==3){memset(map,0,sizeof(map));for(int i=0;i<k;i++){int a,b;scanf("%d %d",&a,&b);map[b][a]=1;}if((m*n-k)%2){printf("NO\n");continue;}nx.clear();for(int i=0;i<1500;i++)ny[i].clear();for(int i=1;i<=m;i++)for(int j=1;j<=n;j++)if(!map[i][j]&& !((i+j)%2) ){map[i][j]=2;nx.push_back((i-1)*n+j);for(int p=0;p<4;p++){int px=i+dir[p][0];int py=j+dir[p][1];if( CanMatch(px,py) ){int u=(i-1)*n+j;int v=(px-1)*n+py;if(!map[px][py]) map[px][py]=3;ny[u].push_back(v);}}}int ans=Hangary();if(ans*2==n*m-k)printf("YES\n");else printf("NO\n");}return 0;}


 

原创粉丝点击