00:00:00
2-SAT 笔记
本文于 2026-05-12 重写。
一、定义
给定长度为
这个问题可以用 2-SAT 解决。
二、解决方法
我们把一个点
如果用
我们根据推理情况建有向图,跑强连通分量,如果存在
当
证明如下:
考虑对于
的建边操作,本质为 、 。 如果取点
和 不可行,说明这样取或导致某个 同时必须取 和 ,即存在路径 和 。 又由建边的对称关系,存在路径
和 ,整理可得存在路径 ,即 的强连通分量拓扑序比 大。
cpp
cin >> n >> m;
for (int i = 1, x, a, y, b; i <= m; i++) {
cin >> x >> a >> y >> b;
add(x + n * (a & 1), y + n * (b ^ 1));
add(y + n * (b & 1), x + n * (a ^ 1));
}
kosaraju();
for (int i = 1; i <= n; i++)
if (scc[i] == scc[i + n]) {
cout << "IMPOSSIBLE";
return 0;
}
cout << "POSSIBLE\n";
for (int i = 1; i <= n; i++)
cout << (scc[i] > scc[i + n]) << " ";三、建图优化
如果有这么一张

举

所以弄两班公交车,一班向右走,一班向左走:

因为

剩下的点同理:

我们成功把边数优化到