二分匹配Hopcroft-Karp算法
2015-07-25 11:08
447 查看
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int N = 110; const int INF=0x7fffffff; int bmap ;//每次记得清空 //对于两边各50000个点,200000条边的二分图最大匹配可以在1s内出解,效果很好:) struct HK{//用HK算法求解二分最大匹配问题(时间复杂度为sqrt(v)*e) int nx,ny,dis; int cx ;//cx[i]表示左集合i顶点所匹配的右集合的顶点序号 int cy ; //cy[i]表示右集合i顶点所匹配的左集合的顶点序号 int dx ; int dy ; int Q ; bool bmask ; bool searchpath(){//极大最短增广路集 int front,rear; front=rear=0;//初始化队列 dis=INF; memset(dx, -1, sizeof(dx)); memset(dy, -1, sizeof(dy)); for(int i=1;i<=nx;i++){ if(cx[i]==-1)//左边未匹配 { Q[rear++]=i;//将左边节点放入队列 dx[i]=0;//分层 所有潜在起点构成0层 } } while(front<rear){ int u=Q[front++];//u都是未匹配的 if(dx[u]>dis)break; for(int v=1;v<=ny;v++){ if(bmap[u][v]&&dy[v]==-1){//相邻未分层构成i+1层。 dy[v]=dx[u]+1;//v对应的距离 为u对应距离加1 if(cy[v]==-1)dis=dy[v];//右侧未匹配,更新最短距离 else{ dx[cy[v]]=dy[v]+1;//右侧已经匹配,根据已匹配边回溯。分层 Q[rear++]=cy[v];//左侧已匹配点入队。 } } } } return dis!=INF; } int findpath(int u){//只搜索极大最短增广路集中的边 for(int v=1;v<=ny;v++){ if(!bmask[v]&&bmap[u][v]&&dy[v]==dx[u]+1){//反向搜索的过程 bmask[v]=1; if(cy[v]!=-1&&dy[v]==dis)continue; if(cy[v]==-1||findpath(cy[v])){ cy[v]=u; cx[u]=v; return 1; } } } return 0; } int Max_match(){ int res=0; memset(cx,-1,sizeof(cx)); memset(cy,-1,sizeof(cy)); while(searchpath()){ memset(bmask, 0, sizeof(bmask)); for(int i=1;i<=nx;i++){ if(cx[i]==-1){ res+=findpath(i); } } } return res; } }; HK hk; //调用的时候确定hk.nx,hk.ny,然后直接调用Max_match()就行
相关文章推荐
- 专业网站和数据下载主页收藏
- shell语法简介
- 项目加载不进去tomcat
- hadoop2.4.1伪分布式搭建
- TOMCAT多站点配置
- CentOS 6.x搭建Open***实现双IDC互联
- Hadoop hdfs增删该查 简单写法
- hadoop Hdfs文件上传下载
- UVa 11078 - Open Credit System(维护最大值)
- centos7 安装R和Rstudio客户端
- Linux之GTK系列教程
- 新浪微博架构
- Openssl rand命令
- OPENCV 学习例程(1)图片读写 色彩空间转换
- JAVA & PHP 结合 开发系统网站
- Openssl oscp命令
- 介紹好用工具:RichCopy (檔案複製與備份的絕佳工具)
- opencv+pcl配置
- Openssl pkcs12命令
- iis中默认网站被误删了,EXCHANGE的OWA不能访问了,请问怎么修复?