Topcoder SRM568 Div1 DisjointSemicircles (二分图染色)
Topcoder SRM568 Div1 DisjointSemicircles (二分图染色)
题意: 给定数轴上排列的 \(2n\) 个点,每个点需要找到另一个点和它匹配,并且以他们为直径两端,向上或者向下作一个半圆
有一些点已经匹配好了,要求判断是否存在一个合法的方案,满足所有的半圆不相交
###思路:
枚举已经确定的匹配半圆的方向(设有 \(m\) 对已匹配),然后 \(O(n)\) 判断自由点是否存在合法方案
判断合法方案的核心性质:
定义一个点的方向为其所连接的半圆的方向(上为0,下为1)
则自由点存在合法方案的充要条件是:
整个序列上每种方向的点数为偶数,且所有已匹配的半圆所覆盖的区间下,和半圆同向的点个数为偶数
必要性:
如果某个半圆下同向点个数为奇数,则必然有一个点与其同向并且不得不连到区间外,这显然不合法
充分性:
一种合法的构造方法是:
按照 \(L\) 从左到右,遍历每个已匹配的半圆,如果包含同向子半圆优先解决同向的子半圆
剩下的点依然是偶数个,从左到右依次和上一个匹配即可
\[\ \]
判断是否存在合法方案
那么问题转化为判断是否存在一种合法的定向方案,使得某一些区间里0/1的个数为偶数
考虑构建二分图染色,令点集 \(V=\{0,1,\cdots,n,0',1',\cdots,n'\}\) ,则 \((u,v)\in E\) 表示 \(col(u)\ne col(v)\)
其中 \(i\) 号节点表示 \(1-i\) 中所有未匹配节点方向的异或和, \(i'\) 表示 \(i\) 的反点 \((i,i')\in E\)
(到这里可以自己想一下怎么连边)
对于已匹配圆 \([L,R]\) (注意不要忘了 \([1,n]\) )
如果它方向为 \(1\) ,显然只需要 \(col(L-1)=col(R)\)
如果方向为0,设 \([L,R]\) 未染色个数为 \(k\) ,则显然有 \(col(L-1)=col(R)\oplus (k\mod 2)\) ,即考虑反向的个数
同时对于已匹配点 \(i\) ,显然有 \(col(i)=col(i-1)\)
由此,得到一个 \(O(n)\) 点数边数的图
如果在 \(\text{dfs}\) 枚举时同步加边和回撤,总复杂度就为 \(O(2^m\cdot n)\)
由于不可能所有方案都合法,实际应该是一个比较松的上界
1 |
|