P4782 【模板】2-SAT 问题 (建图+tarjan求scc+逆拓扑序)

题目链接

在这里插入图片描述

2-SAT问题:有n个bool型的变量,有m个方程(每个方程有且只包含n个bool变量中的2个),
问能否找出满足这m个方程的n个bool变量。

解决2-SAT问题可以利用强连通分量。

一、建有向图

每个变量只有TRUE / FALSE两种选择,我们可以把第i个变量拆成i / i+n两个点,分别表示TRUE / FALSE。再通过方程进行建边,转化成图论问题。

比如方程:x1 | x2 =TRUE (x1 x2至少有一个是true)
可以得到两条有向边:
x1+n -> x2
x2+n -> x1
(x1为假 那么一定可以得出x2为真 ,反之)

那么能否拿x1为真连边呢?不行,因为x1为真,那么x2不管真假都可以,是不确定性的关系,所以不能连边。

这个题目中的方程:x1=p 或 x2=q 至少有一个满足
所以可以建两条有向边:
x1(¬p) -> x2(q)
x2(¬q) -> x1(p)

在这里插入图片描述

二、求出强连通分量

利用tarjan算法求出有向图的SCC,同时顺带求出了缩点后的逆拓扑序。
对于任意一个SCC,其中的每个顶点都是要同时取的值。
在这里插入图片描述

三、取bool值

在缩点后的DAG中,如果i比i+n的拓扑序更大,那么肯定只能取i,因为如果取i+n的话,会指向i,造成i和i+n同时取的错误。

另外,如果i i+n位于同一个SCC中,那么问题无解。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
const int maxn = 2e6+10;
const int mx = 40;
const int mod = 1e9+7;
const ll inf = 34359738370;
const int INF = 1e5;
vector<int> g[maxn];
int dfs_clock,scc_cnt;
int low[maxn],dfn
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值