匈牙利算法(二分图算法
程序员文章站
2022-05-22 19:54:04
...
匈牙利算法用于求二分图的最大匹配:
used[]表示当前这次循环中已经被占用的右边节点,linker[i]记录第i个右边节点归属于那个左边节点,下列u表示左边节点,v表示右边节点。对于邻接矩阵存储的结构:
//先来先得,但是是能让就让
bool dfs(int u){ //对左边的u节点进行分配的调整,若能分配返回true
for(int v=0;v<vN;v++)
if(g[u][v]&&!used[v]){//有边相连,并且**这次**还没考虑过v点
used[v]=1; //只要遍历过的used都置为1
//若右边v节点还没有归属,或者v的原来归属 可以分配另外节点
if(linker[v]==-1||dfs(linker[v])){
linker[v]=u;
return true;
/*只要当前图中存在一个used[i]==0&&linker[i]==-1的v,所有递归就都解决了,
dfs(u)返回的就是true。
1. used==1实际上表示的就是“维持观望”的状态(对于维持观望的位置used==1,
说明这个位置原来有人,但在未找到下家之前,该位置不会腾出,
所以就不用再挤过去),但只要出现一个点的linker[i]=-1没被占用,
那之前维持观望的点都能找到新下家,返回true。
2. 如果大家都是维持观望,说明没有新位置可以腾出,
大家都找不到新下家,返回false*/
}
}
return false;
}
int hungary(){
int res;
for(int u=0;u<uN;u++){
memset(used,0,sizeof(used)); //每次对左边新点做调整时,对used重置
if(dfs(u)) res++; //一次dfs确定左边一个新点u的匹配
}
return res; //返回二分图最大匹配数
}
1538.Gopher II
直接用最大二分图匹配,建图可采用邻接表,对于距离小于s*t的田鼠和洞的组合之间建立一条边,然后用最大二分图匹配让最多的田鼠能入洞,最终答案是没入洞的田鼠数。
做的时候没有对基于vector的邻接表clear更新,要注意对vector以及其他公用结构更新!
上一篇: [算法总结] 二分
下一篇: Spring Bean的种类和作用域