poj2446 Chessboard 二分图最大匹配 思考 匈牙利算法BFS实现
来源:互联网 发布:红蜻蜓软件 编辑:程序博客网 时间:2024/05/19 15:41
POJ 2446 点击打开链接
大致题意:
有一个m*n棋盘,上面有k个洞,你现在有许多个规模为1*2的小卡片。你可以将卡片覆盖在棋盘上(卡片必须整个覆盖在棋盘上),正好覆盖一个1*2的空间,但是不能覆盖有洞的棋盘格子。问,你是否能用一些卡片(不限个数),将棋盘的无洞格子全都覆盖?
例如:
(1):
它是合法的,全部覆盖。
(2)
不合法,因为有一个洞被覆盖了。
(3)
不合法,因为有一个正常的格子没被覆盖。
大致思路:
我们将二维状态转换成一维状态,将棋子编号为1,2,3.....n*m。将这些棋子放在一个集合里,然后将它们的相邻棋子放在另一个集合里。然后能与之相邻的进行连接,这样就构成了二分图。然后寻找最大匹配数(当然,在之前,我们一定将有洞的格子和正常的格子进行了分类),最大匹配数意味着可以找到1*2的空间的最大数。既然我们找到了最大匹配,我们看是否等于n*m-k,是的话,代表我们能成功。
代码:
#include<stdio.h>#include<iostream>#include<string.h>#include<vector>#include<queue>#include<map>using namespace std;typedef pair<int,int>Pa;map<Pa,int>M;int vis[1505],pre[1505];int ml[1505],mr[1505];int flag[1505];//用来区分有洞和无洞的格子vector<int>V[1505];int m,n,k;int MaxMatch()//bfs匈牙利算法寻找最大匹配数{ int sum=0; memset(ml,-1,sizeof(ml)); memset(mr,-1,sizeof(mr)); memset(vis,0,sizeof(vis)); for(int i=1; i<=n*m; i++) { if(!flag[i]&&ml[i]==-1)//这个棋子不是匹配点而且没洞 { //寻找增广路 queue<int>Q; Q.push(i); pre[i]=-1; int kas=0; while(!Q.empty()&&!kas) { int st=Q.front(); Q.pop(); for(int j=0; j<V[st].size()&&!kas; j++) { int to=V[st][j]; if(vis[to]!=i&&!flag[to]) { vis[to]=i; Q.push(mr[to]); if(mr[to]>=0) { pre[mr[to]]=st; } else { kas=1; int d=st,e=to; while(d!=-1) { int temp=ml[d]; ml[d]=e; mr[e]=d; e=temp; d=pre[d]; } } } } } if(kas)sum++; } } return sum;}int main(){ while(~scanf("%d%d%d",&m,&n,&k)) { memset(flag,0,sizeof(flag)); M.clear(); int x,y; for(int i=0; i<k; i++) { scanf("%d%d",&x,&y); M[make_pair(y,x)]=1;//将有洞的格子的二维坐标进行标记 } int ans=1;//棋子编号从1开始 for(int i=1; i<=m; i++)//便利整个棋盘,我们要将二维棋盘转化成一维的,利于操作 { for(int j=1; j<=n; j++) { if(!M[make_pair(i,j)])//这个棋子是正常的 { if(j<n) //将此时的棋子与其相邻的棋子进行“画边” { V[ans].push_back(ans+1); } if(j>1) { V[ans].push_back(ans-1); } if(i<m) { V[ans].push_back(ans+n); } if(i>1) { V[ans].push_back(ans-n); } ans++; } else { flag[ans]=1;//这个编号的棋子是有洞的 ans++; } } } /*for(int i=1; i<=n*m; i++) { if(flag[i])continue; printf("%d:\n",i); for(int j=0; j<V[i].size(); j++) { printf("%2d",V[i][j]); } printf("\n"); }*/ int he=MaxMatch(); if(he+k==n*m) { printf("YES\n"); } else printf("NO\n"); }}
阅读全文
0 0
- poj2446 Chessboard 二分图最大匹配 思考 匈牙利算法BFS实现
- 【二分图最大匹配】【匈牙利算法】poj1469 COURSES && poj2446 Chessboard
- 匈牙利最大匹配 poj2446 Chessboard
- POJ2446 Chessboard【二分图最大匹配】
- 二分图最大匹配---匈牙利算法BFS 实现
- poj1469 二分图最大匹配 匈牙利算法BFS实现
- POJ2446:Chessboard(二分匹配)
- poj2446 Chessboard 二分匹配
- poj2446--Chessboard(二分匹配)
- 【最大匹配】Chessboard POJ2446
- poj2446 Chessboard【最大匹配】
- 【二分图匹配】最大匹配-匈牙利算法BFS && DFS写法
- POJ2446 Chessboard(二分图)
- poj2239 Selecting Courses(最大二分图匹配 (匈牙利算法) 实现 )
- 二分图最大匹配算法-匈牙利算法
- poj2446 && poj1469 二分图最大匹配
- 二分图最大匹配(匈牙利算法)
- 最大二分图匹配(匈牙利算法)
- Hdu 1058 Humble Numbers
- 汉诺塔问题
- 偏移量的问题
- react native:Command /bin/sh failed with exit code 1 报错解决
- pdf阅读器怎么给pdf文件添加图像
- poj2446 Chessboard 二分图最大匹配 思考 匈牙利算法BFS实现
- srand()和rand()
- MySQL 中 delete 语句的子查询限制
- Java实现简单插入排序
- python emoji 表情过滤
- C++11中的std::function,Lambda表达式
- Eclipse上red5插件安装
- 新域名访问方式从http改为https(为了支持微信小程序https用)
- lintcode刷题——搜索旋转排序数组