二分图匹配Hopcroft-Carp算法介绍
2017-10-13 20:25
337 查看
我们在做二分图匹配的时候,最喜欢选择的就是匈牙利算法,但是我们可以知道匈牙利算法的复杂度是O(n*e),那么如果对于一个点和边比较多的图,匈牙利算法很容易超时,所以我们采用Hopcroft-Carp算法来解决这个问题,这个算法能够在 O(sqrt(n)*e)的复杂度内实现二分图匹配。
下面我就来讲一讲这个算法的操作过程。
简单来说,这个算法就是在匈牙利算法的基础上,先通过BFS找到多条不相交最短增广路,并且在这个基础上再往下增广,所以同时可以增广多条路,降低了时间复杂度。
那么我们是怎么实现的呢?
1、我们先将每一个要匹配的点通过BFS找到一个对应最短增广路,形成一个增广路集合
2、对于我们找到增广路集合,我们去匹配这个集合中的每个增广路,(我们用之前的允许弧的方法去记录上面找到的最短不交叉的最短增广路)将他往下延伸。
这样我们再用匈牙利算法去匹配。
算法分析,匈牙利算法是通过对每一个点去增广匹配,现在我们是通过记录一个d数组,实现对每一条路进行增广匹配,同时间增广的效率变高了,所以时间复杂度就降低了。
先贴一份模板:
下面我就来讲一讲这个算法的操作过程。
简单来说,这个算法就是在匈牙利算法的基础上,先通过BFS找到多条不相交最短增广路,并且在这个基础上再往下增广,所以同时可以增广多条路,降低了时间复杂度。
那么我们是怎么实现的呢?
1、我们先将每一个要匹配的点通过BFS找到一个对应最短增广路,形成一个增广路集合
2、对于我们找到增广路集合,我们去匹配这个集合中的每个增广路,(我们用之前的允许弧的方法去记录上面找到的最短不交叉的最短增广路)将他往下延伸。
这样我们再用匈牙利算法去匹配。
算法分析,匈牙利算法是通过对每一个点去增广匹配,现在我们是通过记录一个d数组,实现对每一条路进行增广匹配,同时间增广的效率变高了,所以时间复杂度就降低了。
先贴一份模板:
const int inf=0x3f3f3f3f; int Mx[maxn]; int My[maxn]; int dx[maxn]; int dy[maxn]; bool used[maxn]; int dis,Ny,Nx; bool searchP() { dis=INF; int i,v,u; std::queue<int> Q; memset(dx,-1,sizeof(dx)); //d数组里存放的是增广路到达该点的距离,dx是左边的点,dy是右边的点 memset(dy,-1,sizeof(dy)); for(i=0;i<Nx;i++) { if(Mx[i]==-1) { //遇到没有匹配的点,就开始寻找他的增广路 Q.push(i); dx[i]=0; } } while(!Q.empty()) { u=Q.front(); Q.pop(); if(dx[u]>dis) break; for(v=0;v<Ny;v++) { if(g[u][v]&&dy[v]==-1) { dy[v]=dx[u]+1; if(My[v]==-1) dis=dy[v]; else { //如果这个点已经被匹配了,这条路不是增广路,那么我们就要继续往下找,直到找到一条增广路为止 dx[My[v]]=dy[v]+1; Q.push(My[v]); } } } } return dis!=INF; } bool DFS(int u) { int v; for(v=0;v<Ny;v++) { if(g[u][v]&&!used[v]&&dy[v]==dx[u]+1) //现在我们找到一条边,并且这个点刚好是我们找增广路时候的下一个点,说明这两个点有匹配的需要 { used[v]=true; if(My[v]!=-1&&dy[v]==dis) continue; //此时说明已经找到最后一个点了,它并不是一个增广路,就放弃这条路 if(My[v]==-1||DFS(My[v])) { My[v]=u; Mx[u]=v; return true; } } } return false; } //这里就和匈牙利算法没有什么区别了 int Hungary() { int u; int ret=0; memset(Mx,-1,sizeof(Mx)); memset(My,-1,sizeof(My)); while(searchP()) { memset(used,false,sizeof(used)); for(u=0;u<Nx;u++) if(Mx[u]==-1&&DFS(u)) ret++; } return ret; }
相关文章推荐
- 二分图匹配(Hopcroft-Carp的算法)模版:
- Hopcroft-Carp算法模板【二分图匹配】
- HDU 2389 Rain on your Parade (二分图匹配(Hopcroft-Carp的算法模板))
- 二分图匹配(Hopcroft-Carp的算法) 模版
- HDU2389(二分图匹配Hopcroft-Carp算法)
- 二分图匹配——Hopcroft-Carp算法模板
- HDU2389_Rain on your Parade_二分图匹配::Hopcroft-Carp模板题
- HDU2063-过山车[Hopcroft-Carp]二分图匹配
- ACM HDU 2389 Rain on your Parade(二分匹配 Hopcroft-Carp的算法)
- HDU 2389 Rain on your Parade(Hopcroft-Carp算法板子题)
- POJ 3894 System Engineer 二分图匹配 Hopcroft_Carp 最大流
- HDU 2389 Rain on your Parade(二分匹配,Hopcroft-Carp算法)
- LightOJ-1356-二分图匹配Hopcroft-Carp+数论
- 【模板】解决二分图匹配的强力算法——Hopcroft-Karp算法
- 【转】二分图匹配 匈牙利算法介绍
- [算法] 匈牙利算法 poj 1274 示例 [ 二分图匹配 入门篇 ] O(n*m) Hopcroft O(sqrt(n)*m)
- kuangbin专题十 HDU2389(Hopcroft-Carp的算法模板)
- hdu 2389 Rain on your Parade(二分匹配Hopcroft-Carp算法模版)
- [算法] 匈牙利算法 poj 1274 示例 [ 二分图匹配 入门篇 ] O(n*m) Hopcroft O(sqrt(n)*m)
- OpenJ_POJ - 1013Excellent Note (二分图最大匹配Hopcroft_carp算法)