匈牙利算法主要用来解决两个问题:求二分图的最大匹配数和最小点覆盖数。
最大匹配问题相当于,假如你是红娘,可以撮合任何一对有暧昧关系的男女,那么你最多能成全多少对情侣?
我们从B1看起(男女平等,从女生这边看起也是可以的),他与G2有暧昧,那我们就先暂时把他与G2连接(注意这时只是你作为一个红娘在纸上构想,你没有真正行动,此时的安排都是暂时的)。
来看B2,B2也喜欢G2,这时G2已经“名花有主”了(虽然只是我们设想的),那怎么办呢?我们倒回去看G2目前被安排的男友,是B1,B1有没有别的选项呢?有,G4,G4还没有被安排,那我们就给B1安排上G4。
然后B3,B3直接配上G1就好了,这没什么问题。至于B4,他只钟情于G4,G4目前配的是B1。B1除了G4还可以选G2,但是呢,如果B1选了G2,G2的原配B2就没得选了。我们绕了一大圈,发现B4只能注定单身了,可怜。(其实从来没被考虑过的G3更可怜)
#include <cstdio>#include <cstring>int Map[205][205], p[205], vis[205], N, T;bool match(int i){for (int j = 1; j <= N; ++j){if (Map[i][j] && !vis[j]){// 访问过的标记为1vis[j] = 1;// 递归查询右图,匹配成功立刻返回trueif (p[j] == 0 || match(p[j])){p[j] = i;return true;}}}return false;}int Hungarian(){int cnt = 0;for (int i = 1; i <= N; ++i){memset(vis, 0, sizeof(vis));if (match(i))cnt++;}return cnt;}
