poj2446 2010.2.21
来源:互联网 发布:webuploader demo源码 编辑:程序博客网 时间:2024/05/22 06:19
poj2446 2010.2.21
http://blog.chinaunix.net/u3/102624/showart_2060827.html
题意:
玩个游戏:给出一个m行n列的棋盘,里面有m*n个方格,其中有k个格子上有洞,我们称那些没洞的格子叫正常的格子(normal grid),Bob要遵循两个规则去玩:(1)任何一个正常的格子都要被一张卡覆盖,(卡片是1*2规格的)(2)一张卡要正好覆盖两个相邻的正常格子
我们的任务是帮助Bob决定是否棋盘在上述两个规则下能被覆盖。
思路:
因为棋盘上都是两个格子放一张卡片,所以到最后肯定是两个点两个点连着的。由此想到了二分匹配,具体是这样的:
给每个格子编号,从第一行到最后一行编号为1—12 ,然后每个点跟临近的正常点连接,这就建成了二分图,如右上图。
然后以此建邻接表,建表时,枚举每个点,如果是正常点i,那么与他相邻的正常点(v)的邻接点数增一(g[v][0]++),并使g[v][g[v][0]] = i;
然后就是二分匹配模版了,完后看匹配数是否等于正常格子数,即是否能构成完美匹配。
wa
#include <stdio.h>#include <string.h>#define MAXN 400+10int map[MAXN][MAXN];int mid[MAXN][MAXN];int link[MAXN],f[MAXN];int n,m,num1,num2,ans=0;int path(int t){int i;for(i=1;i<=n;i++){if (f[i]==0&&map[t][i]){f[i]=1;if(link[i]==-1||path(link[i])){link[i]=t;return 1;}}}return 0;}int EK(){int sum=0;int i;memset(link,-1,sizeof(link));for(i=1;i<=n;i++){memset(f,0,sizeof(f));if(path(i)) sum++;}return sum;}int main(){scanf("%d %d %d",&num1,&num2,&m);int i,j;memset(map,0,sizeof(map));memset(mid,1,sizeof(mid));for(i=1;i<=num1;i++){mid[i][0]=0;mid[i][num2+1]=0;}for(i=1;i<=num2;i++){mid[0][i]=0;mid[num1+1][i]=0;}n=num1*num2-m;int a,b;for(i=1;i<=m;i++){scanf("%d %d",&a,&b);mid[b][a]=0;}for(i=1;i<=num1;i++)for(j=1;j<=num2;j++)if (mid[i][j]){ans++;mid[i][j]=ans;}for(i=1;i<=num1;i++)for(j=1;j<=num2;j++)if (mid[i][j]){if (mid[i-1][j])map[mid[i-1][j]][mid[i][j]]=1;if (mid[i+1][j])map[mid[i+1][j]][mid[i][j]]=1;if (mid[i][j-1])map[mid[i][j-1]][mid[i][j]]=1;if (mid[i][j+1])map[mid[i][j+1]][mid[i][j]]=1;}if (EK()==n)printf("YES\n");else printf("NO\n");return 0;}
标称:
#include <stdio.h>#include <string.h>#include <conio.h>#define N 34#define M N*Nint g[M][5], used[M], mat[M];int match, m, n;int find(int k){ int i, j; for(i=1; i<=g[k][0]; i++) { j = g[k][i]; if(!used[j]) { used[j] = 1; if(!mat[j] || find(mat[j])) { mat[j] = k; return 1; } } } return 0;}void hungary(){ int i; for(i=1; i<=m*n; i++) { if(g[i][0] != -1 && g[i][0] != 0) { match += find(i); memset(used, 0, sizeof(used)); } }}int main(){ int i, j; int k; int x, y; freopen("in.txt", "r", stdin); scanf("%d%d%d", &m, &n, &k); for(i=1; i<=k; i++) { scanf("%d%d", &x, &y); g[x+(y-1)*n][0] = -1; } for(i=1; i<=m*n; i++) { if(g[i][0] != -1) { //left if((i-1)%n >= 1 && g[i-1][0] != -1) g[i-1][++g[i-1][0]] = i; //right if(i%n != 0 && g[i+1][0] != -1) g[i+1][++g[i+1][0]] = i; //up if((i-(i%n)) / n >= 1 && g[i-n][0] != -1) g[i-n][++g[i-n][0]] = i; //down if((i-(i%n)+1) / n <= m && g[i+n][0] != -1) g[i+n][++g[i+n][0]] = i; } } match = 0; hungary(); if(match == m*n-k) printf("YES\n"); else printf("NO\n"); //printf("%d\n", match); getch(); return 0;}
0 0
- poj2446 2010.2.21
- poj2446
- poj2446
- poj2446
- POJ2446
- poj2446 Chessboard
- poj2446 Chessboard
- POJ2446 Chessboard
- poj2446 Chessboard
- POJ2446--Chessboard
- POJ2446 CHESSBOARD
- POJ2446【建图建图】
- POJ2446 二分图应用
- POJ2446:Chessboard(二分匹配)
- 【最大匹配】Chessboard POJ2446
- poj2446 Chessboard 二分匹配
- POJ2446 二分匹配
- poj2446--Chessboard(二分匹配)
- HDU 找出直系亲属 (dfs+vector)
- hdoj--3488--Tour(KM)
- 说说JAVA I/O流的那些事
- Windows Server 2003 磁盘镜像卷实现双硬盘数据灾难备份 2012
- poj1469 2010.2.21
- poj2446 2010.2.21
- 组建XP双硬盘软阵列经验
- js全局变量和局部变量
- 在iar环境下,把一个普通的stm32工程上移植入ucosii
- PAT (Basic Level)1010. 一元多项式求导
- Android GridView 的简单例子
- “高帅穷”与“矮挫富”
- 转载:windows.2003.应用"网络负载平衡管理器"实现均衡负载与双机热备 .
- logback与Spring、SpringMVC结合使用教程