UOJ #704. 马超战潼关
显然题目相当于最小割计数。
考虑一个最大匹配,则一条匹配路径 \((S,x),(x,y),(y,T)\) 三条边中肯定要割一条边掉。因此一个暴力做法是枚举割哪条,然后看 \(S\) 和 \(T\) 是否联通。
考虑一条不在最大匹配上的边 \((u,v)\),若 \(u\) 不在最大匹配中,则 \((v,T)\) 必须割,若 \(v\) 不在最大匹配中,则 \((S,u)\) 必须割,否则 \((S,u),(v,T)\) 必须割一条。
抽象一下,每个点可以选 \(0,1,2\),限制是某个点必须选某个数或者 \(u=0,v=2\) 至少要满足一个。
直接折半可以做到 \(O(3^{\frac{n}{2}}\operatorname{poly}(n))\),但是不牛。考虑一条依次经过匹配边和非匹配边的环,则经过的所有匹配边都不能选,并且所有的匹配选的数要相同,因此可以缩点,然后对于一个限制 \((u,v)\),从 \(u\) 所在的匹配连向 \(v\) 所在的匹配就是一个 DAG。
跑出这个 DAG 的一个拓扑序,这样就只有前面的点对后面的点有限制,限制形如某个点是否必须选 \(2\)。
现在直接搜索就是 \(O(2^n)\) 的,因为当我们搜到某个位置并确定这个位置的 \(2\) 能不能选的时候,这个位置的 \(2\) 和 \(1\) 是等价的,因此每个点只需要搜索 \(2\) 种情况。
直接记忆化,前 \(\frac{n}{2}\) 步是 \(O(2^{\frac{n}{2}}n)\) 的,后 \(\frac{n}{2}\) 步因为限制只有 \(2^{n-i}\) 种,所以也是 \(O(2^{\frac{n}{2}}n)\) 的。
可以去掉 map 做到 \(O(2^{\frac{n}{2}})\),但是实测前面的跑得更快,感性上 map 其实去除了更多的无用状态,前面 \(\frac{n}{2}\) 的搜索如果在同一个联通块中肯定有比较强的限制,复杂度应该是低于 \(O(1.414^n)\) 的。