二分图优化
$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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步