[POJ] 2446 Chessboard(二分图最大匹配)
2015-03-30 17:03
190 查看
题目地址:http://poj.org/problem?id=2446
本题建图是关键。因为卡片都是1*2,所以若点V被某个1*2卡片覆盖,则周围包含V的其它1*2区域都不成立。所以想到只要把V点划分在X集合,周围点在Y集合,V向周围点分别连边,就变成了二分图匹配问题,区分点V与周围点可以用横纵坐标之和的奇偶性。若棋盘上除障碍外都能被1*2卡片覆盖,则最大匹配数ans=(棋盘所有点数n*m-障碍数k)/2。本题在进行之前还有一个小优化,如果n*m-k是奇数,显而易见是不成立的,所以直接返回NO。
本题建图是关键。因为卡片都是1*2,所以若点V被某个1*2卡片覆盖,则周围包含V的其它1*2区域都不成立。所以想到只要把V点划分在X集合,周围点在Y集合,V向周围点分别连边,就变成了二分图匹配问题,区分点V与周围点可以用横纵坐标之和的奇偶性。若棋盘上除障碍外都能被1*2卡片覆盖,则最大匹配数ans=(棋盘所有点数n*m-障碍数k)/2。本题在进行之前还有一个小优化,如果n*m-k是奇数,显而易见是不成立的,所以直接返回NO。
#include<cstdio> #include<iostream> #include<string.h> #include<algorithm> #include<math.h> #include<stdbool.h> #include<time.h> #include<stdlib.h> #include<set> #include<map> #include<stack> #include<queue> #include<vector> using namespace std; #define clr(x,y) memset(x,y,sizeof(x)) #define sqr(x) ((x)*(x)) #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define LL long long #define INF 0x3f3f3f3f #define A first #define B second #define PI 3.14159265358979323 const int N=2000+11; const int dx[4]={0,0,1,-1}; const int dy[4]={1,-1,0,0}; int n,m,k1,k,k2,f ,g ,link ,flag ,a ,b ; void init() { clr(f,0); clr(g,0); clr(flag,0); clr(a,0); clr(b,0); clr(link,-1); k1=0; k2=0; } bool find(int x) { for(int i=0;i<k2;i++) { if(!f[b[i]] && g[x][b[i]]) { f[b[i]]=1; if(link[b[i]]==-1 || find(link[b[i]])) { link[b[i]]=x; return true; } } } return false; } int hungary() { int ans=0; for(int i=0;i<k1;i++) { clr(f,0); if(find(a[i])) ans++; } return ans; } int main() { int u,v,x,y; init(); scanf("%d%d%d",&m,&n,&k); if((m*n-k)&1) { printf("NO\n"); return 0; } for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) flag[i][j]=1; } for(int i=1;i<=k;i++) { scanf("%d%d",&y,&x); flag[x][y]=0; } for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { int p=(i-1)*n+j; if((i+j)&1) { if(flag[i][j]) a[k1++]=p; } else { if(flag[i][j]) b[k2++]=p; } } } for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { if(flag[i][j]) for(int k=0;k<4;k++) { int nx=i+dx[k]; int ny=j+dy[k]; if(flag[nx][ny]) { g[(i-1)*n+j][(nx-1)*n+ny]=1; } } } } if(2*hungary()+k==n*m) printf("YES\n"); else printf("NO\n"); return 0; }
相关文章推荐
- POJ 2446 Chessboard(二分图最大匹配)
- poj 2446 Chessboard 二分图最大匹配经典题
- POJ2446 Chessboard【二分图最大匹配】
- POJ 2446Chessboard(二分图最大匹配)
- poj 2446 Chessboard 二分图的最大匹配
- POJ 2446 Chessboard (二分图最大匹配)
- POJ 2446 Chessboard(二分图最大匹配)
- POJ - 2446 Chessboard 二分图 最大匹配(输入坑)
- POJ 2446 Chessboard 二分图的最大匹配 <建图>
- poj--2446 Chessboard(二分图最大匹配)
- POJ 2446-Chessboard(二分图_最大匹配)
- 【二分图+最大匹配】北大 poj 2446 Chessboard
- POJ 2446 Chessboard(二分图最大匹配)
- POJ 2446 Chessboard(二分图最大匹配)
- poj 2446 Chessboard(二分图最大匹配)
- poj 2446 Chessboard (二分图利用奇偶性匹配)
- poj 2446 二分图最大匹配 匈牙利算法
- 【二分图最大匹配】【匈牙利算法】poj1469 COURSES && poj2446 Chessboard
- POJ-2446 Chessboard 最大匹配
- poj 2446 Chessboard (二分图利用奇偶性匹配)