poj 2446二分图匹配
2013-04-03 15:05
288 查看
题意:爱丽丝和波波经常玩棋盘游戏,爱丽丽画出一个m*n的棋盘,让波波在棋盘中填充1*2大小的矩形条,而且爱丽丝不想这么轻易让波波赢,她将m*n的棋盘中挖掉k个方格。
1.每个矩形条必需覆盖矩阵中相临两个方格
2.矩形条不能覆盖挖去的方格。
对于给定的m*n的且某些方格被挖去的矩阵,问用某种覆盖方法能否将除挖掉的方格外所有方格全部覆盖,若能,输出YES,否则输出NO。
思路:
矩形条每次覆盖相临两个方格。那么对两个任意方格(看作结点),如果它们分属两个不同的集合的话,那么它们之间存在边的情况只有它们是相临的方格的时候。这样一来,我们可以将矩阵中所有元素分成两个点集,相临点间存在边的关系。那么如何分这两个集合呢, 发现一个方块的行标和列标之和若为奇数则它周围的四个方块的行标和列标之和必为偶数;一个方块的行标和列标之和若为偶数则它周围的四个方块的行标和列标之和必为奇数,奇数一个集合,偶数一个集合,只连左边和上边。这样一个二分图就建完了。
1.每个矩形条必需覆盖矩阵中相临两个方格
2.矩形条不能覆盖挖去的方格。
对于给定的m*n的且某些方格被挖去的矩阵,问用某种覆盖方法能否将除挖掉的方格外所有方格全部覆盖,若能,输出YES,否则输出NO。
思路:
矩形条每次覆盖相临两个方格。那么对两个任意方格(看作结点),如果它们分属两个不同的集合的话,那么它们之间存在边的情况只有它们是相临的方格的时候。这样一来,我们可以将矩阵中所有元素分成两个点集,相临点间存在边的关系。那么如何分这两个集合呢, 发现一个方块的行标和列标之和若为奇数则它周围的四个方块的行标和列标之和必为偶数;一个方块的行标和列标之和若为偶数则它周围的四个方块的行标和列标之和必为奇数,奇数一个集合,偶数一个集合,只连左边和上边。这样一个二分图就建完了。
// File Name: 2446.cpp // Author: Missa // Created Time: 2013/4/3 星期三 13:56:33 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<string> #include<vector> #include<cstdlib> #include<map> #include<set> using namespace std; #define CL(x,v) memset(x,v,sizeof(x)); #define R(i,st,en) for(int i=st;i<en;++i) #define LL long long #define inf 0x3f3f3f3f const int maxn = 33; int n,m,k; int in[maxn][maxn]; int g[maxn * maxn][maxn * maxn]; int nx,ny; bool vis[maxn * maxn]; int link[maxn * maxn]; bool dfs(int x) { R(y, 1, ny+1) { if(!vis[y] && g[x][y]) { vis[y] =1; if(link[y] == -1 || dfs(link[y])) { link[y] = x; return 1; } } } return false; } int maxmatch() { int ans = 0; CL(link,-1); R(x, 1, nx+1) { CL(vis, 0); if(dfs(x)) ans++; } return ans; } void init() { nx = ny = 0; CL(g, 0); for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { if (in[i][j] == -1) continue; if ((i + j) & 1) { in[i][j] = ++nx; if (i - 1 >= 1 && in[i-1][j] != -1) g[nx][in[i-1][j]] = 1; if (j - 1 >= 1 && in[i][j-1] != -1) g[nx][in[i][j-1]] = 1; } else { in[i][j] = ++ny; if (i - 1 >= 1 && in[i-1][j] != -1) g[in[i-1][j]][ny] = 1; if (j - 1 >= 1 && in[i][j-1] != -1) g[in[i][j-1]][ny] = 1; } } } } int main() { while(~scanf("%d%d%d",&n, &m, &k)) { CL(in, 0); R(i, 0, k) { int x, y; scanf("%d%d", &y, &x); in[x][y] = -1; } if((n * m - k) & 1) { printf("NO\n"); continue; } init(); if(maxmatch() * 2 == (n * m - k)) printf("YES\n"); else printf("NO\n"); } return 0; }
相关文章推荐
- POJ 2446 Chessboard (二分图匹配)
- POJ_2446_Chessboard(二分图匹配)
- poj 2446 (二分图匹配)
- POJ 2446 Chessboard【二分图匹配】
- POJ 2446 Chessboard(二分图匹配)
- POJ 2446 Chessboard二分图匹配
- poj 2446(二分图匹配-通俗易懂)
- Chessboard - POJ 2446 二分图匹配
- POJ 2446 Chessboard(二分图匹配)
- POJ 2446 Chessboard(二分图匹配)
- poj 2446 二分图匹配,匈牙利算法
- POJ 2446 Chessboard (二分图匹配)
- POJ 2446 Chessboard (二分图匹配)
- POJ 2446 二分图匹配
- POJ-2446 邻接表+二分图匹配
- POJ 2446 Chessboard(二分图匹配)
- Poj 2446 Chessboard 匈牙利算法
- POJ 2536 Gopher II (ZOJ 2536) 二分图匹配
- POJ 1486 Sorting Slides【二分图匹配】
- POJ2536 二分图匹配