POJ 2446 Chessboard(二分匹配-hungary)
2015-12-31 13:20
399 查看
Description
一个n*m的棋盘,棋盘上有k个洞,问能否用1*2的纸片恰好覆盖所有不是洞的格子,所谓恰好就是所有不是洞格子都被覆盖且只被覆盖一次
Input
第一行三个整数n,m和k分别表示棋盘行列数以及洞的数量,之后k行每行两个整数i和j表示这个洞位于棋盘第i行第j列
Output
如果恰能用1*2的纸片覆盖所有不是洞的格子则输出YES,否则输出NO
Sample Input
4 3 2
2 1
3 3
Sample Output
YES
Solution
二分匹配,将每一个不是洞的格子看作一个点,显然一个1*2纸片覆盖的两个格子行列和的奇偶性不同,所以可以将此题转化为两排点的二分匹配,一排点行列和为奇,另一排行列和为偶,对于每一个不是洞且行列和为奇的格子,将其与其上下左右四个格子中不是洞的格子建边,最后看最大匹配数的二倍是否等于n*m-k,是则说明可行,否则不行
Code
一个n*m的棋盘,棋盘上有k个洞,问能否用1*2的纸片恰好覆盖所有不是洞的格子,所谓恰好就是所有不是洞格子都被覆盖且只被覆盖一次
Input
第一行三个整数n,m和k分别表示棋盘行列数以及洞的数量,之后k行每行两个整数i和j表示这个洞位于棋盘第i行第j列
Output
如果恰能用1*2的纸片覆盖所有不是洞的格子则输出YES,否则输出NO
Sample Input
4 3 2
2 1
3 3
Sample Output
YES
Solution
二分匹配,将每一个不是洞的格子看作一个点,显然一个1*2纸片覆盖的两个格子行列和的奇偶性不同,所以可以将此题转化为两排点的二分匹配,一排点行列和为奇,另一排行列和为偶,对于每一个不是洞且行列和为奇的格子,将其与其上下左右四个格子中不是洞的格子建边,最后看最大匹配数的二倍是否等于n*m-k,是则说明可行,否则不行
Code
#include<cstdio> #include<iostream> #include<cstring> using namespace std; #define maxn 1111 int uN,vN;//u,v数目 int g[maxn][maxn];//编号是0~n-1的 int linker[maxn]; bool used[maxn]; bool dfs(int u) { int v; for(v=0;v<vN;v++) if(g[u][v]&&!used[v]) { used[v]=true; if(linker[v]==-1||dfs(linker[v])) { linker[v]=u; return true; } } return false; } int hungary() { int res=0; int u; memset(linker,-1,sizeof(linker)); for(u=0;u<uN;u++) { memset(used,0,sizeof(used)); if(dfs(u)) res++; } return res; } int main() { int n,m,k,Map[33][33]; while(~scanf("%d%d%d",&n,&m,&k)) { memset(g,0,sizeof(g)); uN=vN=0; memset(Map,0,sizeof(Map)); for(int i=1;i<=k;i++) { int x,y; scanf("%d%d",&x,&y); Map[y][x]=-1; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(Map[i][j]==-1)continue; if((i+j)%2)Map[i][j]=uN++; else Map[i][j]=vN++; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(Map[i][j]!=-1&&((i+j)%2)) { if(i-1>=1&&Map[i-1][j]!=-1)g[Map[i][j]][Map[i-1][j]]=1; if(i+1<=n&&Map[i+1][j]!=-1)g[Map[i][j]][Map[i+1][j]]=1; if(j-1>=1&&Map[i][j-1]!=-1)g[Map[i][j]][Map[i][j-1]]=1; if(j+1<=m&&Map[i][j+1]!=-1)g[Map[i][j]][Map[i][j+1]]=1; } if(hungary()*2==m*n-k)printf("YES\n"); else printf("NO\n"); } return 0; }
相关文章推荐
- 锐捷认证成功但是无法上网的问题
- win7下在VMware中设置防火墙打开/关闭
- js跳转页面方法实现汇总
- Compass用法指南
- ubuntu下如何用命令行运行deb安装包
- 菜鸟说: 线程那点事(java篇)
- OpenCV行人检测
- Fresco 中文文档: Fresco | Fresco 中文说明
- cas实现单点登录
- Best Practices for YARN Resource Management
- 创建数据库表空间和分配用户权限
- 卷及神经网络CNN for image retrieval
- 【冷知识】在python2.7或更早的版本中模拟类似3.x的print函数
- x64不同平台的调用约定
- 关于红杏的公益代理, Android Studio以及freso的编译
- Java Hibernate:调试 Jsp 时重启 Tomcat 以禁用缓存
- 知道指针地址 , 怎么取出指针指向的内容??? 0x7fff5fbff564 这种值 怎么赋值给一个变量??
- JNI - 如何将 char 转换成 jstring
- CVPR15 image retrieval reading list
- 运算符:三目运算符,运算符优先级,sizeof,自增自减,取余