首页 > 其他分享 >2-SAT 问题入门

2-SAT 问题入门

时间:2023-12-07 21:13:47浏览次数:30  
标签:2000005 入门 int 问题 low oplus 性质 SAT

前言

1.本文在非代码部分用 \(T\) 代替 \(true\),\(F\) 代替 \(false\)。

2.本文对于具体的问题解答,只涉及P4782 【模板】2-SAT 问题,其他类型(如连接符号为“与”、“异或”)暂不涉及。

3.请预习强连通相关知识。

4.本文中的“到达”和“可达”指由 \(i\) 点经过一些单向边后可以到达 \(j\) 点。

5.本文中的 \(\oplus\) 代表异或运算。

SAT(SATISFIABILITY)

中文名是布尔可满足性问题,又名命题可满足性问题。

本人不会。

2-SAT

目前只有 \(2-SAT\) 问题可以用非暴力方法解决。一般问题见P4782 【模板】2-SAT 问题

一般来说, \(O(2^n)\) 的枚举做法适用于所有 \(SAT\) 问题,同样适用于 \(2-SAT\) 问题。但既然把 \(2-SAT\) 单独拿出来讲,那么这个问题一定就有更优的方法:就是在多项式时间复杂度中用图去解决。

考虑 \(2\) 这个数的性质,想像在C++语言下形似这些表达式的式子:

((! x[i]) && x[j]) == true   [1]
(x[i] || (! x[j])) == true   [2]
(x[i] ^ (! x[j])) == true    [3]

我们会发现,当知道 \(x_i\) 和 \(x_j\) 其中一个布尔变量的值时,我们就有可能将另一个值求出来(当然第一个的值可以直接推得)。

而在 \([2]\) 式中,若已知 $x_i= F $ 或 \(x_j = T\),就可以得到另一个变量的值;但若已知 \(x_i=T\) 或 \(x_j=F\),另一个变量就可以任取。

大家自己想一想 \([3]\) 式。

所以在本题中,我们就可以利用这一个性质进行问题的判断有无解以及求一个解。

具体解答

对于上文的性质以及所对应的约束条件,我们可以进行建图。

对于每个布尔变量 \(x_i\) 建立两个点 \(a_{i,0}\) 和 \(a_{i,1}\),分别代表 \(x_i=F\) 和 \(x_i=T\) 这两种情况,而我们若连单向边 \(a_{p, 0} \to a_{q,1}\),则表示:若 \(x_p = F\) 则 \(x_q = T\) (当然,如果:1.若 \(x_p=T\),则我们不能通过这条边求出 \(x_q\) ;2.若 \(x_q=T\), 我们也无法通过这条边求出 \(x_p\))。

性质一

因为成立性的传递,所以若 \(a_{i,0}\) (即 \(x_i = F\))成立且能够通过单向边到达 \(a_{j,0}\),则 \(a_{j,0}\) (即 \(x_j=F\))必须成立,否则原表达式组不成立。

性质二

当:由 \(a_{i,0}\) 可以到达 \(a_{i,1}\) 由 \(a_{i,1}\) 可以到达 \(a_{i,0}\) 时,原表达式组不成立。

因为很显然,\(a_{i,0}\) 的情况(即 \(x_i = F\)) 和 \(a_{i,1}\) 的情况(即 \(x_i=T\))有且只有一个会成立。

当满足上述条件时,要么两个条件都满足,否则就都不满足。这显然与我们的要求和实际不符合。

性质三

本问题的建图具有对称性,即:若存在边 \(a_{p, 0} \to a_{q,1}\),则一定存在 \(a_{q,0} \to a_{p,1}\)。扩展结论,可得:若 \(a_{p,0}\) 可达 \(a_{q,1}\),则 \(a_{q,0}\) 可达 \(a_{p,1}\)。

我们可以通过对原表达式分析得出这个结论。

性质四

在有解的情况下,若 \(a_{i,0}\) 能够到达 \(a_{i,1}\),那么 \(a_{i,1}\) 一定成立。

Tarjan 缩点解决

观察性质一和二,很容易想到缩点后进行某些操作来求解。

当然,若 \(a_{i,0}\) 和 \(a_{i,1}\) 被缩进一个点中,则原表达式组不成立。

然后,我们就得到了一个简单有向无环图。

这时感性理解一下,缩点后的图仍然满足对称性(比较显然)。

这是我们可以对新图进行拓扑排序。

就算有不同的拓扑序,总有一个很神奇的性质:

性质五(极其重要)

设:

\(a_{i,p}\) 的拓扑序为 \(f(a_{i,p})\)。

引理:

此时对于原表达式组一定有解,且对于任意拓扑序都有其中一组解满足:

若 \(f(a_{i,0})<f(a_{i,1})\) 则 \(a_{i,0}=T,x_i = F\),否则 \(a_{i, 1}=T,x_i = T\)。

证:

设存在 \(a_{i,p}, a_{i,p \oplus 1},a_{j,q},a_{j,q \oplus 1}\)。

又不妨设:

\[f(a_{i,p})<f(a_{i,p \oplus 1}), f(a_{j, q}) < f(a_{j,q \oplus 1}) \]

根据原命题,所以:

\[a_{i,p}=a_{j,q}=T,a_{i,p\oplus 1}=a_{j,q\oplus 1}=F \]

分类讨论:

一、

\(a_{i,p\oplus 1}\) 不可达 \(a_{j, q}\)。

由性质三可知,一定有 \(a_{j,q\oplus 1}\) 不可达 \(a_{i, p}\)。

1.\(a_{i,p\oplus 1}\) 不可达 \(a_{j,q\oplus 1}\):

所以 \(a_{j,q}\) 不可达 \(a_{i,p}\)。

所以没有约束关系,这部分正确。

2.\(a_{i,p\oplus 1}\) 可达 \(a_{j, q\oplus 1}\):

所以 \(a_{j,q}\) 可达 \(a_{i, p}\)。

我们知道 \(a_{i,p}=a_{j,q}=T,a_{i,p\oplus 1}=a_{j,q\oplus 1}=F\),所以满足条件。

二、

\(a_{i,p\oplus 1}\) 可达 \(a_{j,q}\)。

由性质三可知,一定有 \(a_{j,q\oplus 1}\) 可达 \(a_{i,p}\)。

因为 \(a_{i,p\oplus 1}\) 可达 \(a_{j,q}\),所以:

\[f(a_{j,q})>f(a_{i,p\oplus 1}) \]

因为 \(a_{j,q\oplus 1}\) 可达 \(a_{i,p}\),所以:

\[f(a_{i,p})>f(a_{j,q\oplus 1}) \]

因为 \(f(a_{i,p})<f(a_{i,p\oplus 1})\),所以:

\[f(a_{j,q\oplus 1})<f(a_{i,p})<f(a_{i,p\oplus 1})<f(a_{j,q}) \]

这与我们规定的 \(f(a_{j,q})<f(a_{j,q\oplus1})\) 冲突,故这种情况不成立。

三、

\(i,j\)可交换,如上同理,成立。

故对于任意 \(i,j\) 都满足条件。

即证。

然后我们利用这个性质,就可以解决构造解的问题了。

Code

#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, a, b;
int firs[2000005], nex[2000005], to[2000005], tot;
int idx, dfn[2000005], low[2000005], sta[2000005], top, cnt, bel[2000005];
bool vis[2000005];
void Add (int u, int v){
	++ tot;
	nex[tot] = firs[u];
	firs[u] = tot;
	to[tot] = v;
}
int G (int i, int j){
	return i + j * n;
}
void Tarjan (int u){
	if (dfn[u])
		return ;
	dfn[u] = low[u] = ++ idx;
	sta[++ top] = u;
	vis[u] = true;
	for (int e = firs[u];e;e = nex[e]){
		int v = to[e];
		if (! dfn[v]){
			Tarjan (v);
			low[u] = min (low[u], low[v]);
		} else
		if (vis[v])
			low[u] = min (low[u], dfn[v]);
	}
	if (dfn[u] == low[u]){
		int v;
		++ cnt;
		do {
			v = sta[top --];
			bel[v] = cnt;
			vis[v] = false;
		} while (u != v);
	}
}
int main (){
	scanf ("%d%d", &n, &m);
	for (int i = 1;i <= m;++ i){
		scanf ("%d%d%d%d", &x, &a, &y, &b);
		Add (G (x, a ^ 1), G (y, b));
		Add (G (y, b ^ 1), G (x, a));
	}
	for (int i = 1;i <= (n << 1);++ i)
		Tarjan (i);
	for (int i = 1;i <= n;++ i)
		if (bel[G (i, 0)] == bel[G (i, 1)]){
			printf ("IMPOSSIBLE\n");
			return 0;
		}
	printf ("POSSIBLE\n");
	for (int i = 1;i <= n;++ i)
		printf ("%d ", (int) (bel[G (i, 1)] < bel[G (i, 0)]));
	return 0;
}

标签:2000005,入门,int,问题,low,oplus,性质,SAT
From: https://www.cnblogs.com/imcaigou/p/17883952.html

相关文章

  • tiktok电商入门完整教程,新手小白一定要看
    随着短视频的兴起,越来越多的人开始关注如何在TikTok上开展电商业务。对于新手小白来说,了解如何入门并快速掌握TikTok电商运营技巧至关重要。本文将为您提供一份完整的TikTok电商入门教程,帮助您从零开始构建自己的电商业伴来详细了解一下吧。一、了解TikTok电商模式TikTok电商主要是......
  • 前端问题记录:el-row和el-col出现排版错乱
    el-row和el-col出现排版错乱,如图使用场景:使用了el-row和col配合form使用,不操作时候页面排版是正确的,进行操作就会出现排版错乱。问题原因:因为el-row和el-col的中的span元素之和超过了24的时候,就会出现排版错乱解决方案:.el-row{display:flex;//设置布局flex-wrap:wrap;//......
  • 可能是全网最好的 Spock 单测入门文章!
    可能是全网最好的Spock单测入门文章!Spock是非常简洁规范的单元测试框架,网上很多资料都不齐全,例子也很难懂。我自己经过一段时间的学习,梳理了这篇文章,不仅讲解层次递进,而且还有非常简洁明了的例子,小白都能懂!快速入门Spock使用Spock非常简单,只需要引入对应的Spock依赖......
  • 记录一个debian11环境下更新源失败问题
    之前用的阿里云源,时间久了不知道为何拉取失败。网上搜教程替换管理其他国内镜像源。配置方法原文件备份sudocp/etc/apt/sources.list/etc/apt/sources.list.bak编辑源列表文件sudovim/etc/apt/sources.list将原来的清单内容删除或注释,并增加镜像源地址,这里推荐......
  • Java Mockito 快速入门指南 Mock是指使用Mockito创建的模拟对象,它模拟真实对象的行为,
    JavaMockito快速入门指南Mock是指使用Mockito创建的模拟对象,它模拟真实对象的行为,用于替代真实对象的依赖项,以便进行独立的单元测试在软件开发中,单元测试对于确保代码的正确性和可靠性至关重要。Mockito是一个强大的Java测试框架,它提供了丰富的功能和方法,使得编写模拟测试变得......
  • 天池AI练习生计划 - 第二期AI数学基础入门与实践,火热进行中!通关赢取双重礼品!
    机器视觉学术研究与产品研发专家雷明,带领您详细学习人工智能领域需要用到的数据知识点,从学习者蜕变为AI新星!轻松来闯关,即可领取双重礼品~实训培训证书:通关两个关卡即可领取阿里云定制长袖T恤:通关全部关卡即可领取活动地址:https://tianchi.aliyun.com/specials/promotion/math......
  • 天池AI练习生计划 - 第二期AI数学基础入门与实践,火热进行中!通关赢取双重礼品!
    机器视觉学术研究与产品研发专家雷明,带领您详细学习人工智能领域需要用到的数据知识点,从学习者蜕变为AI新星!轻松来闯关,即可领取双重礼品~实训培训证书:通关两个关卡即可领取阿里云定制长袖T恤:通关全部关卡即可领取活动地址:https://tianchi.aliyun.com/specials/promotion/math......
  • 很多学员通过考试并已挂靠机构开始实习,但审核过程并非纸上谈兵,三体系的审核过程中应该
    01质量管理体系审核中常见问题点001.文件控制 A、内部文件的审批、分发、更改:1)工程图纸未经审批即已发行、使用;2)作业指导书未能分发至具体作业岗位;3)生产现场岗位悬挂的作业指导书未受控;4)工艺文件存在直接在文件上更改的现象,未执行文件更改程序。B、外来文件的识别、收集......
  • HydroOJ 从入门到入土(5)插件集锦
    总有些需求,未必有啥用,但是很可爱.本文将介绍一些插件相关的知识,并不专业,因为我不懂js(逃目录1.关于插件2.官方插件3.三方插件4.官方站上的第三方插件1.关于插件插件使用js/ts语言编写.插件功能强大,分前后端,可以干任何事情,所以尽量不要使用来路不......
  • postgresql从入门到精通 - 第37讲:postgres物理备份和恢复概述
       PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUGPG技术大讲堂。 第37讲:物理备份和恢复概述 第37讲:12月09日(周六)19......