匈牙利算法
众所周知,匈牙利算法是一种算法
第一次接触匈牙利算法是在一次模拟赛中的第三题导弹,这道题要A国一些点负责一个必过的点,这种情况下我们要最优,但单纯判断有无重复是不行的,因为一个点最优(贪心)不代表全局最优,所以我们要先用二分枚举答案,再用匈牙利算法来验证
讲了那么多其实匈牙利算法就是给出两类东西(一类>=二类),第一类东西都有自己可以接受的第二类(但只能选一个),看第二类是否都能被选到
下图为图文结合,更加简洁易懂
首先下列各线表达的是一类可以接受的二 (繁体) 类,如图所示
然后最秀的一开始,很显然,壹没人要,直接带走
然后二找到了贰,也是直接带走
然后三想找壹,一看在他挺可怜的,就让给了他
然后一去抢贰,二身为巨佬,十分大方地让给了他
然后二找到了肆
然后四找到了叁
然后五想抢叁,但若要给他,四就没人了(三选了壹,一就只能选贰,二就只能选肆,所以,四不能选肆)
所以结果是二类全被要到了,而一类只有五没要到
SO,这就是匈牙利算法的过程
代码实现:
bool js(int xx)//第xx个一类
{
int l=0;//用于记录
for (int i=head[xx];i;i=f[i].next)//枚举xx与xx可以接受的每一个二类之间线
if (!pd[f[i].to])//可以诚恳地向他要
{
l=bg[f[i].to];//记录下原主人
bg[f[i].to]=xx;//暂时要过来
pd[f[i].to]=true;//防止原主人又过来要,然后造成死循环
if ((!l)||(js(l))) return true;//要不本来没人要,要不原主人找到别的二类了
bg[f[i].to]=l;//没法要这个就还给他
}
return false;//全程下来还没找到就是“凉”了
}
这里个是先枚举每一个一类再来判断他要到没有,还要在每一回清空pd数组