dfs,bfs的二分匹配模板(模板题hdu1150)
2016-04-29 11:45
387 查看
如果不懂匈牙利算法,请点击:该趣味算法/article/1613615.html
模板:
//DFS版本下的二分匹配算法
http://paste.ubuntu.net/16122581/
//BFS版本下的二分匹配算法
http://paste.ubuntu.net/16122732/
模板:
//DFS版本下的二分匹配算法
http://paste.ubuntu.net/16122581/
#include<cstdio> #include<iostream> #include<vector> #include<set> #include<map> #include<math.h> #include<queue> #include<stdlib.h> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; //DFS版本下的二分匹配算法 const int MAXN = 300; //最大顶点数 bool bmap[MAXN][MAXN]; //二分图 bool bmask[MAXN]; //寻找增广路径的标志数组 int nx,ny; //nx为左顶点的个个数,ny为右顶点的个数 int cx[MAXN]; //cx[i]表示左集合i顶点所匹配到的右集合的顶点的序号。 int cy[MAXN]; //cy[i]表示右集合i顶点所匹配到的左集合的顶点的序号。 int k; int findpath(int u) { int i; for(i=0;i<ny;i++) //扫描每个妹子 { //如果【有暧昧】并且【还没有标记过】 //这里标记的意思是这次查找【曾】试图改变过该妹子的归属问题 //但是没有成功,所以就不用瞎费工夫了 if(bmap[u][i]&&!bmask[i]) { bmask[i]=1; if(cy[i]==-1||findpath(cy[i])) //名花无主 或者 能腾出个位置来,这里使用递归 { cy[i]=u; cx[u]=i; return 1; } } } return 0; } int MaxMatch() { int res=0; //有多少对 int i,j; for(int i=0;i<nx;i++) cx[i]=-1; for(int i=0;i<ny;i++) cy[i]=-1; for(int i=0;i<nx;i++) //为男生找配偶 { if(cx[i]==-1) { for(int j=0;j<ny;j++) //这个在每一步中清空 bmask[j]=0; res+=findpath(i); } } return res; } int main() { while(~scanf("%d",&nx)&&nx) { scanf("%d%d",&ny,&k); int x; memset(bmap,0,sizeof(bmap)); int a,b; for(int i=0;i<k;i++) { scanf("%d%d%d",&x,&a,&b); if(a>0&&b>0) bmap[a][b]=1; } int ans=MaxMatch(); printf("%d\n",ans); } return 0; } /* 2 2 3 0 1 1 1 2 1 2 2 2 */
//BFS版本下的二分匹配算法
http://paste.ubuntu.net/16122732/
#include<cstdio> #include<string.h> #include<iostream> using namespace std; typedef long long LL; //BFS版本下的二分匹配算法 //我觉得DFS的很好理解,所以我觉得套用DFS的讲,可能有偏差; const int MAXN = 1000; //最大顶点数 int bmap[MAXN][MAXN]; //二分图 int cx[MAXN]; //cx[i]表示左集合i顶点所匹配到的右集合的顶点的序号。 int cy[MAXN]; //cy[i]表示右集合i顶点所匹配到的左集合的顶点的序号。 int nx,ny,k; //nx为左顶点的个个数,ny为右顶点的个数 int bmask[MAXN]; //寻找增广路径的标志数组 int que[MAXN]; //队列保存扩展顶点 int pre[MAXN]; //记录前置顶点 int MaxMatch() { int res=0; int qs,qe; memset(cx,-1,sizeof(cx)); memset(cy,-1,sizeof(cy)); memset(bmask,-1,sizeof(bmask)); for(int i=0;i<nx;i++) { if(cx[i]==-1) //为男的寻找配偶 { qs=qe=0; //队列初始化 que[qe++]=i; pre[i]=-1; bool flag=0; while(qs<qe&&!flag) { int u=que[qs]; for(int v=0;v<ny&&!flag;v++) { if(bmap[u][v]&&bmask[v]!=i) //如果有关系,但是这个关系并不是给我们要配对的男生 { bmask[v]=i; //但是...该男子强行拿过来作为妻子 que[qe++]=cy[v]; //所以女生本来的丈夫就很伤了 if(cy[v]>=0) //如果那个人有丈夫的话,就用pre记录前置节点 { pre[cy[v]]=u; } else //但是该女子没有丈夫,那就是刚刚好 { flag=1; //OK解决问题 int d=u,e=v; while(d!=-1) //然后这就是类似于DFS算法中的回溯,这建立了改男子配对下的状态是什么样子的。 { int t=cx[d]; cx[d]=e;cy[e]=d; d=pre[d];e=t; } } } } qs++; } if(cx[i]!=-1) //有多少配对的男子,就加几个 { res++; } } } return res; } int main() { while(~scanf("%d",&nx)&&nx) { scanf("%d%d",&ny,&k); int x; memset(bmap,0,sizeof(bmap)); int a,b; for(int i=0;i<k;i++) { scanf("%d%d%d",&x,&a,&b); if(a>0&&b>0) bmap[a][b]=1; } int ans=MaxMatch(); printf("%d\n",ans); } return 0; }
相关文章推荐
- 整数分割
- parent pom文件配置
- 160428、JavaScript知识总结—cookie及其应用
- java 框架个人心得
- 第二章 Docker的核心概念和安装
- 抽象类和接口的区别
- Android FragmentManager BackStackRecord.run throwing NullPointerException
- 游戏运维通用python简易脚本
- 源码推荐(04.29):iOS动画Demo,HR_W仿QQ页面
- 内存管理二之映射篇
- mysql 常用命令
- 了解ASP.NET MVC几种ActionResult的本质:EmptyResult & ContentResult
- libcurl 文件上传
- 160427、CSS3实战笔记--多列布局
- CentOS 6.5通过yum安装 MySQL-5.5
- 大漠对象的创建
- Android实现 UDP
- Android实现RecyclerView自定义列表、点击事件以及下拉刷新
- iOS中正则表达式的使用方法及学习介绍
- Git和github使用方法总结