二分图优化

$For$ $Example$ $:$

bool DFS(int x)
{
for(register int u = first[x], v; u+1; u = e[u].nex)
if(book[v=e[u].to]-id)
{
book[v] = id;
if(!match[v] || DFS(match[v]))
{
match[x] = v, match[v] = x;
return true;
}
}
return false;
}
int Hungary()
{
int ans = 0;
for(register int i = id = 1; i <= 10000; i++, id++)
if(DFS(i))
ans++;
else
break;
return ans;
}

这里使用时间戳$id$代替$memset$减少常数

$Part $ $2$

一般的二分图完美匹配,求最小字典序的通解 算法 $1:$

枚举全排列,再看能否完美匹配。时间复杂度 $O(2nmn)$。
算法 $2:$

从前往后枚举,对于每一个点,从小到大假设它与谁匹配,如果它匹配后剩下的图仍构成完美匹配,就说明它可以与当前儿子匹配,删掉这个点与其匹配点。时间复杂度 $O(m^2n)$。
算法 $3:$

在算法 2 中,每假设当前点 $x$ 与某个点 $y$ 匹配,就要对整个图跑一次二分图匹配,但实际上大多点在这次匹配操作后是没有影响的。所以我们可以先在开始时对整个图跑一次二分图匹配。经过分析,我们可以发现把 $x$ 与 $y$ 匹配只会影响两个点:目前与 $x$ 匹配的点与目前与 $y$ 匹配的点。所以每次只用对影响的这两个点中的任意一个点跑一次增广路就可以了。时间复杂度 $O(m(m+n))$。

至此,我们已经找到了在较低时间复杂度内对一般的二分图完美匹配求最小字典序的方法了。对于不是完美匹配的,需要通过网络流实现,由于我还没学网络流,所以无法在此展开叙述。

本文作者:Saka_Noa

本文链接:https://www.cnblogs.com/Saka-Noa/p/17808455.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Saka_Noa  阅读(14)  评论(0编辑  收藏  举报  
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开