Problem
N个变量,每个变量只有2种可能的取值。再给M个条件,形如“若变量A[i]赋值为A(i, p),那么变量A[j]就必须赋值为A(j, q)”,其中p,q∈[0, 1]。问是否存在合法赋值,满足所有条件。
Solution
(1)建立2*N个节点的有向图,每个A[i]对于两个节点,不妨设为i和i + N。
(2)考虑每个条件,从i + p * N发出有向边到j + q * N。
(3)对于每个条件的逆否命题(原命题与逆否命题等效),即“若变量A[j]赋值为A(j, 1 - q),则A[i]必须赋值为A[i, 1 - p]”,这个也要连边的。(但是如果题里条件给了这个,那连重边也没什么意义)
现在,这张图成了二分图,且连边(不算方向)对称。
(4)用Tarjan求出所有强连通分量。
(5)若存在i∈[1, N],满足i与i + N在同一个分量中,则表明:若A[i]赋值为A(i, p),则A[i]必须赋值为A(i, 1 - p)。矛盾,无解。所以若所有i都不满足这个条件,就有解。
复杂度:O(N + M)。
那如何构造出呢?
※若一个SCC中的任意一个点被赋值,那么这个SCC就固定了。所以我们可以考虑缩点。
中间的步骤我并没有看懂,所以留坑。
有一个很好的优化,Tarjan求强连通分量时,回溯时会优先取出有向图“底部”的SCC进行标记。故,本身就已经满足了DAG中“自底向上”的拓扑序。
所以我们不用缩点直接确定。直接比较belong[i](所在SCC的编号),就能得出val[i]。若val[i] = 1,则X[i]应取X(i, 1),否则取X(i, 0)。
明天再coding。