dfs,bfs的二分匹配模板(模板题hdu1150)
来源:互联网 发布:java ant下载 编辑:程序博客网 时间:2024/06/03 17:18
如果不懂匈牙利算法,请点击:该趣味算法http://blog.csdn.net/dark_scope/article/details/8880547
模板:
//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 30 1 11 2 12 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;}
0 0
- dfs,bfs的二分匹配模板(模板题hdu1150)
- hdu1150 二分图最大匹配模板
- 二分图的判定模板(dfs,bfs)
- 二分匹配DFS实现模板
- hdu1150(二分图匹配模版题)
- 二分匹配(模板)
- 二分匹配模板()
- ACM_模板_二分图匹配(匈牙利算法)-DFS
- 二分图最大匹配(匈牙利算法-DFS增广模板)
- 二分图匹配匈牙利算法(DFS, BFS两种实现模板)
- HDU2063(二分图匹配模板题)
- 二分图匹配 Hdu1150
- BFS和DFS模板
- BFS&&DFS模板
- BFS/DFS 模板 代码
- BFS/DFS 模板 代码
- BFS/DFS 模板 代码
- BFS/DFS模板
- 数据结构与算法——有向无环图的拓扑排序C++实现
- 前端开发知识点
- TreeMap树状映射表
- java 框架个人心得
- 架构设计:系统间通信(28)——Kafka及场景应用(中1)
- dfs,bfs的二分匹配模板(模板题hdu1150)
- github配置学习笔记【windows】
- parent pom文件配置
- 整数分割
- web前端面试题及答案 css篇
- QT+OpenGL开发实例:扫描线填充算法
- 这是我真实的,零基础自学编程,找到满意工作的经历。
- Android布局的优化
- python中使用fork创建新的进程