2-SAT问题

导引: AA, BB, CC 三人中有两个女生
如果 AA 是男生,那么 BB 一定是女生:
AA 和 CC 性别相同
求 AA BB CC 三人的性别

# 2 - SAT问题

# 定义

要确定N个bool类型的值,使得其满足所有的限制关系(每个限制关系最多只对两个bool变量进行限制)

2-SAT问题是有多项式解法的,而3-SAT问题就是npc问题

# 判断是否有解

建立2N个点的有向图,不妨设
ii 点表示 x[i]=×x[i] = \times
i′i' 点表示 x[i]=✓x[i] = \checkmark
一条 u→vu \rightarrow v 的有向边表示如果选择了 uu ,那么一定要选择 vv
不能出现 i↔i′i \leftrightarrow i'
判断i和i'是否位于同一强连通分量即可

# 输出可行方案

如果从 ii 点出发可以到达 i′i' 点,则旋律i会导致选 i′i' ,矛盾,因此只能选 i′i'
Kosaraju算法在求强连通分量时顺带求出了一个遍历顺序 q[1],q[2],...,q[cnt]q[1], q[2], ..., q[cnt]
只需要比较i和i'所属强连通分量在q中位置的前后关系即可构造出可行方案

# 一元限制的构图方案

限制: x[i]=✓x[i] = \checkmark
连边: i→i′i \rightarrow i'
表示如果 ii 选了 ×\times 那么 ii 必须要是 ✓\checkmark

# 二元限制的构图方案

一条边 u→vu \rightarrow v 的含义:若 uu 则 vv
命题”若 uu 则 vv “的逆否命题为”若非 vv 则非 uu “
命题于逆否命题等价
所以在建 u→vu \rightarrow v , 也要建 v→u′v \rightarrow u'
所以对于每条二元限制,将其对应的命题与逆否命题的边连上,缺一不可

建图例:
限制: u∣v=✓u | v = \checkmark
(有一个满足 ✓\checkmark 就行) u→v′,v→u′u\rightarrow v', v\rightarrow u'

建图例:
限制: u∣v=×u | v = \times
(两者都要 ×\times 回到一元限制关系) u′→u,v→v′u'\rightarrow u, v\rightarrow v'

建图例:
限制: u&v=×u \And v = \times
(两个没有同时满足) u′→v,v′→uu'\rightarrow v, v'\rightarrow u

建图例:
限制: u&v=✓u \And v = \checkmark
(两个都要满足) u′→u,v′→vu'\rightarrow u, v'\rightarrow v

建图例:
限制: u≠vu \neq v
(两个情况不同) u′→v,u→v′,v′→u,v→u′u'\rightarrow v, u\rightarrow v', v'\rightarrow u, v\rightarrow u'

建图例:
限制: u=vu = v
(两个情况相同) u′→v′,u→v,v′→u′,v→uu'\rightarrow v', u\rightarrow v, v'\rightarrow u', v\rightarrow u

# 例题

有 nn 对夫妻被邀请参加一个聚会,因为场地的问题,每对夫妻中只有 11 人可以列席
在 2n2n 个人中,某些人之间有着很大矛盾(夫妻之间没有),主办方希望有矛盾的两个人不能同时出现在聚会上
问有没有可能回有 nn 个人同时列席?
思路:
建立 2n2n 个点的图,i点表示第i对夫妻是丈夫到场, i′i' 点表示妻子到场
如果 AA 和 BB 矛盾,则可以表示”若 AA 则非 BB “、”若 BB 则非 AA “。

# 强连通分量求出后的处理

bool res = 1;
for(int i = 0; i < N; i ++){
    if(nod[i] == nod[trans(i)]){
        res = 0;
        break;
    }
}
if(res) cout << "YES" << endl;
else    cout << "NO"  << endl;

//i'可以使用便宜量,表示为i + n(与带权并查集类似)
1
2
3
4
5
6
7
8
9
10
11

# 例题

TT 个 33 人队伍,每个队伍有一个队长
每个队伍要么队长回家,剩下两个留校,要么队长留校,剩下两人回家
给定 MM 条限制,每条限制指定两个人 AA 和 BB ,要求 AA 和 BB 不能同时留校
判断是否有合法方案
思路:
建立 6T6T 个点的有向图, ii 点表示第 ii 个人留校, i′i' 点表示第 ii 个人回家
对于每个队伍 xx , yy , zz ,其中 xx 为队长
xx 和 yy 的选择不同,按照 x≠yx\neq y 连边
xx 和 zz 的选择不同,按照 x≠zx\neq z 连边
yy 和 zz 的选择不同,按照 y=zy=z 连边
对于每条限制 AA ,BB ,两人不能同时留校
若 AA 留校,则 BB 回家: A→B′A\rightarrow B'
若 BB 留校,则 AA 回家: B→A′B\rightarrow A'

Last Updated: 10/14/2023, 7:51:49 PM