研究了几个小时,终于明白了。说穿了,就是你从二分图中找出一条路径来,让路径的起点和终点都是还没有匹配过的点,并且路径经过的连线是一条没被匹配、一条已经匹配过,再下一条又没匹配这样交替地出现。找到这样的路径后,显然路径里没被匹配的连线比已经匹配了的连线多一条,于是修改匹配图,把路径里所有匹配过的连线去掉匹配关系,把没有匹配的连线变成匹配的,这样匹配数就比原来多1个。不断执行上述操作,直到找不到这样的路径为止。
备个份,后面用到再加题目
M67大神的几句话讲解:http://www.matrix67.com/blog/archives/39
二分图最大匹配问题匈牙利算法
bool 寻找从k出发的对应项出的可增广路
{
while (从邻接表中列举k能关联到顶点j)
{
if (j不在增广路上)
{
把j加入增广路;
if (j是未盖点 或者 从j的对应项出发有可增广路)
{
修改j的对应项为k;
则从k的对应项出有可增广路,返回true;
}
}
}
则从k的对应项出没有可增广路,返回false;
}
void 匈牙利hungary()
{
for i->1 to n
{
if (则从i的对应项出有可增广路)
匹配数++;
}
输出 匹配数;
}
模板代码:
bool find (int x)
{
for (int i=0;i<G[x].size ();i++){
Edge& e=theEdge[G[x][i]];
if (!vis[e.to]){
vis[e.to]=1;
if (match[e.to]==0 || find (match[e.to])){
match[e.to]=x;
return true;
}
}
}
return false;
}
int hungary ()
{
int cnt=0;
memset (match,0,sizeof (match));
for (int i=0;i<n;i++){
memset (vis,0,sizeof (vis));
if (find (g2l[i]))
cnt++;
}
return cnt;
}