POJ 2446 Chessboard(二分图最大匹配)
2017-08-17 22:52
411 查看
POJ 2446 Chessboard(二分图最大匹配)
http://poj.org/problem?id=2446
题意:
给出一个矩形N*M棋盘,有K个格子是空洞,然后用2*1的矩形,对所有非空洞的格子进行覆盖,如果可以全部覆盖,就puts("YES");
分析:
首先一个空的N*M棋盘必然是二分图.对于(r,c)格子,r+c为偶数与r+c为奇数分别属于二分图的两个点集.(可以自己验证下)
然后本题的一些格子是空洞,那么就把这些格子排除.把剩下的格子按照它们所属的二分图点集分类编号. 且对于邻接的两个格子,在二分图的邻接矩阵g上标记true表示有边即可.那么我们添加一个2*1矩形在相邻两个非空洞格子上,就表示二分图的一个匹配了,那么本题就变成了问该二分图是否存在完全匹配问题。
(注意剪枝)
我在这题的时候一心图快,” which represents a hole in the y-th row, the x-thcolumn”这句话没仔细看,直接悲剧1小时,真是悲剧.下次一定要认真看题.
AC代码:
http://poj.org/problem?id=2446
题意:
给出一个矩形N*M棋盘,有K个格子是空洞,然后用2*1的矩形,对所有非空洞的格子进行覆盖,如果可以全部覆盖,就puts("YES");
分析:
首先一个空的N*M棋盘必然是二分图.对于(r,c)格子,r+c为偶数与r+c为奇数分别属于二分图的两个点集.(可以自己验证下)
然后本题的一些格子是空洞,那么就把这些格子排除.把剩下的格子按照它们所属的二分图点集分类编号. 且对于邻接的两个格子,在二分图的邻接矩阵g上标记true表示有边即可.那么我们添加一个2*1矩形在相邻两个非空洞格子上,就表示二分图的一个匹配了,那么本题就变成了问该二分图是否存在完全匹配问题。
(注意剪枝)
我在这题的时候一心图快,” which represents a hole in the y-th row, the x-thcolumn”这句话没仔细看,直接悲剧1小时,真是悲剧.下次一定要认真看题.
AC代码:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; struct Max_Match { int p,n;//左右两点集的点个数 bool g[1100][1100];//邻接矩阵,g[i][j]=true表示从左边第i个节点到右边第j个节点有边 int left[1100];//left[i]==j表右边第i个点与左边第j个点匹配,为-1表无点匹配 bool vis[1100];//表右边第i个点是否已经被访问过 void init() { memset(g,0,sizeof(g)); memset(left,-1,sizeof(left)); } bool match(int i) { for(int j=1;j<=n;j++)if(g[i][j] && !vis[j]) { vis[j]=true; if(left[j]==-1 || match(left[j]) ) { left[j]=i; return true; } } return false; } int solve() { int ans=0;//记录匹配边数目 for(int i=1;i<=p;i++) { memset(vis,0,sizeof(vis)); if(match(i)) ans++; } return ans; } }MM; int maps[50][50]; int id[50][50]; int go[4][2]={0,1,0,-1,1,0,-1,0}; int main() { int k; int x,y; int n,m; while(~scanf("%d%d%d",&n,&m,&k)) { MM.init(); memset(maps,0,sizeof maps); 4000 memset(id,-1,sizeof id); for(int i=1;i<=k;i++) { scanf("%d%d",&y,&x); maps[x][y]=1; } int cnt1=0,cnt2=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(!maps[i][j]) { if((i+j)%2) { id[i][j]=++cnt1; } else { id[i][j]=++cnt2; } } } MM.p=cnt1,MM.n=cnt2; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(maps[i][j]||(i+j)%2==1)continue; else { for(int k=0;k<4;k++) { x=i+go[k][0]; y=j+go[k][1]; if(x>=1&&x<=n&&y>=1&&y<=m) { if(!maps[x][y]) { MM.g[id[i][j]][id[x][y]]=1; } } } } } if(cnt1!=cnt2||(m*n-k)%2==1) { printf("NO\n"); continue; } if(MM.solve()*2==(n*m-k)) printf("YES\n"); else printf("NO\n"); } return 0; }
相关文章推荐
- 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 2446Chessboard(二分图最大匹配)
- [POJ] 2446 Chessboard(二分图最大匹配)
- 【二分图+最大匹配】北大 poj 2446 Chessboard
- POJ 2446-Chessboard(二分图_最大匹配)
- POJ 2446 Chessboard(二分图最大匹配)
- poj 2446 Chessboard(二分图最大匹配)
- POJ2446 Chessboard【二分图最大匹配】
- poj Chessboard 2446 (最大匹配&转换)
- poj 2446 Chessboard (二分图利用奇偶性匹配)
- POJ-2446 Chessboard 最大匹配
- poj 2446 二分图最大匹配
- poj 2446 二分图 最大匹配