【任务】
给定一个二分图,用匈牙利算法求这个二分图的最大匹配数。
【说明】
求最大匹配,那么我们希望每一个在左边的点都尽量找到右边的一个点和它匹配。
我们一次枚举左边的点x的所有出边指向的点y,
若y之前没有被匹配,那么(x,y)就是一对合法的匹配,我们将匹配数加一,
否则我们试图给原来匹配的y和x'重新找一个匹配,如果x'匹配成功,那么(x,y)就可以新增为一对合法的匹配。
给x'寻找匹配的过程可以递归解决。
【接口】
int hungary();
复杂度O(|E|*sqrt(|V|))
输入: n 全局变量,左侧的点数
g 全局变量,g[i]表示与左边点i相连的右边的点
输出:tot 最大匹配数
from 全局变量,from[i]表示最大匹配图中与左边点i相连的边
【代码】
//输入: const int MAXN = 555; // 数组长度 int n = 200; //n表示左侧的点数 vector <int> g[MAXN]; // 表示与左边点i相连的右边点 //输出: int from[MAXN];//表示最大匹配中与左边点i相连的边 int tot; // 二分图最大匹配数 bool use[MAXN]; // 左边点的使用标记 //匈牙利算法 模板题 ,match和hungary见小红书ACM国际大学生程序设计竞赛 算法与实现 bool match(int x){ for(int i = 0;i < g[x].size(); ++i){ if(!use[g[x][i]]){ use[g[x][i]] = true; if(from[g[x][i]] == -1 || match(from[g[x][i]])){ from[g[x][i]] = x; return true; } } } return false; } int hungary(){ tot = 0; memset(from,255,sizeof(from)); for(int i = 1;i <= n; i++){ memset(use,0,sizeof(use)); if(match(i)) ++tot; } return tot; }
这个我打算写给自己写题学习时用的,发出来供大家参考。