2-SAT (two-statisfiability) 算法 学习笔记
$2-SAT$问题指的是对于若干限制求出一组可行解的问题。
考虑对于$n$个值域为${0,1}$的变量$x_1 , x_2 ,...,x_n$ 满足若干限制:
若 $x_i = p$ 则 $x_j = q ( i,j\in[1,n],p,q \in \{0,1\})$
我们考虑对于每一个变量$x_i$开一个值域$x_{i,0} , x_{i,1}$表示第$i$个变量取值为$0/1$的点。
然后考虑每一组命题, 若 $x_i = p$ 则 $x_j = q , i,j\in[1,n],p,q \in \{0,1\}$ ,
首先把$x_{i,p}$和$x_{j,q}$两个点连一条单向边。
并且 由于这个命题非常特殊,值域大小只为2 , 其逆否命题也是限制(可以显然的反证)。
于是就把$x_{j,1-q}$和$x_{i,1-p}$ 连一条单向边。
然后对于上面的图跑tarjan找出scc,如果$x_{i,0}$和$x_{i,1}$在同一连通块中了,
说明下列命题成立: “若$x_i = 0$则$x_i = 1$ ” ,“若$x_i = 1$则$x_i = 0$ ” 所以此时答案无解。
如何构造出一组解呢,由于tarjan的dfs特性,
设$c_i$表示通过tarjan算法求出的连通块编号(这本身就是逆拓扑序的)。
$val_i = c_{x_{i,0}} > c_{x_{i,1}}$ 就构造出$val_i , i\in [1,n]$一组合法解了。
P4782 【模板】2-SAT 问题
设变量$x_i \in \{0,1\}$ ,给出若干组关系:$x_i = p $ 或者 $x_j = q$
如果$x_i , (i\in [1,n])$有解,先输出"POSIBLE"然后输出一组合法解。
如果$x_i , (i\in [1,n])$无解,则输出"IMPOSIBLE"即可。
对于100%的数据$n,m\leq 10^6$
Sol:
$x_i$为$p$ 或 $x_j$为$q$ 可以拆成$2\times 2$对逻辑关系。
- 若$x_i$为$1-p$,则$x_j$为$q$ , 若$x_j$为$1-q$,则$x_i$为$p$
- 若$x_j$为$1-q$,则$x_i$为$p$ , 若$x_i$为$1-p,$ 则$x_j$为$q$
实现方面,只需:$[1,N]$为原来元素的$0$域,$[N+1,2N]$ 为原来元素的$1$域.
# include <bits/stdc++.h>
using namespace std;
const int N=2e6+,M=4e6+;
struct rec{ int pre,to;}a[M];
stack<int>s;
bool ins[N];
int cnt,tot,n,m,head[N],c[N],dfn[N],low[N],val[N];
void adde(int u,int v)
{
a[++tot].pre=head[u];
a[tot].to=v;
head[u]=tot;
}
void tarjan(int u)
{
dfn[u]=low[u]=++dfn[];
s.push(u);ins[u]=;
for (int i=head[u];i;i=a[i].pre){
int v=a[i].to;
if (!dfn[v]) {
tarjan(v);
low[u]=min(low[u],low[v]);
} else if (ins[v]) low[u]=min(low[u],dfn[v]);
}
if (dfn[u]==low[u]) {
cnt++; int v;
do {
v=s.top(); s.pop();
ins[v]=; c[v]=cnt;
} while (u!=v);
}
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=m;i++) {
int s,ps,t,pt; scanf("%d%d%d%d",&s,&ps,&t,&pt);
adde(s+(-ps)*n,t+pt*n); adde(t+(-pt)*n,s+ps*n);
adde(t+(-pt)*n,s+ps*n); adde(s+(-ps)*n,t+pt*n);
}
for (int i=;i<=*n;i++) if (!dfn[i]) tarjan(i);
for (int i=;i<=n;i++) if (c[i]==c[i+n]) {
puts("IMPOSSIBLE"); return ;
}
for (int i=;i<=n;i++) val[i]=c[i]>c[n+i];
puts("POSSIBLE");
for (int i=;i<=n;i++) printf("%d ",val[i]); puts("");
return ;
}
2-SAT (two-statisfiability) 算法 学习笔记的更多相关文章
- C / C++算法学习笔记(8)-SHELL排序
原始地址:C / C++算法学习笔记(8)-SHELL排序 基本思想 先取一个小于n的整数d1作为第一个增量(gap),把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组 ...
- Manacher算法学习笔记 | LeetCode#5
Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...
- Johnson算法学习笔记
\(Johnson\)算法学习笔记. 在最短路的学习中,我们曾学习了三种最短路的算法,\(Bellman-Ford\)算法及其队列优化\(SPFA\)算法,\(Dijkstra\)算法.这些算法可以快 ...
- 某科学的PID算法学习笔记
最近,在某社团的要求下,自学了PID算法.学完后,深切地感受到PID算法之强大.PID算法应用广泛,比如加热器.平衡车.无人机等等,是自动控制理论中比较容易理解但十分重要的算法. 下面是博主学习过程中 ...
- Johnson 全源最短路径算法学习笔记
Johnson 全源最短路径算法学习笔记 如果你希望得到带互动的极简文字体验,请点这里 我们来学习johnson Johnson 算法是一种在边加权有向图中找到所有顶点对之间最短路径的方法.它允许一些 ...
- 算法学习笔记——sort 和 qsort 提供的快速排序
这里存放的是笔者在学习算法和数据结构时相关的学习笔记,记录了笔者通过网络和书籍资料中学习到的知识点和技巧,在供自己学习和反思的同时为有需要的人提供一定的思路和帮助. 从排序开始 基本的排序算法包括冒泡 ...
- R语言实现关联规则与推荐算法(学习笔记)
R语言实现关联规则 笔者前言:以前在网上遇到很多很好的关联规则的案例,最近看到一个更好的,于是便学习一下,写个学习笔记. 1 1 0 0 2 1 1 0 0 3 1 1 0 1 4 0 0 0 0 5 ...
- 二次剩余Cipolla算法学习笔记
对于同余式 \[x^2 \equiv n \pmod p\] 若对于给定的\(n, P\),存在\(x\)满足上面的式子,则乘\(n\)在模\(p\)意义下是二次剩余,否则为非二次剩余 我们需要计算的 ...
- SPFA算法学习笔记
一.理论准备 为了学习网络流,先水一道spfa. SPFA算法是1994年西南交通大学段凡丁提出,只要最短路径存在,SPFA算法必定能求出最小值,SPFA对Bellman-Ford算法优化的关键之处在 ...
- 算法学习笔记(三) 最短路 Dijkstra 和 Floyd 算法
图论中一个经典问题就是求最短路.最为基础和最为经典的算法莫过于 Dijkstra 和 Floyd 算法,一个是贪心算法,一个是动态规划.这也是算法中的两大经典代表.用一个简单图在纸上一步一步演算,也是 ...
随机推荐
- [转帖]ASML发布Q1季度财报 营收22.3亿欧元,EUV光刻机下半年产能大增 ...
ASML发布Q1季度财报营收22.3亿欧元,EUV光刻机下半年产能大增 ... 孟宪瑞发布于2019-4-18 10:32 https://www.expreview.com/67969.html 一 ...
- selenium爬虫后上传数据库。
一.准备工作 1.1安装软件 安装python.安装谷歌浏览器.将chromedriver.exe放到指定位置.放到Scripts文件夹中.我这边的路径为:C:\Users\1\AppData\Loc ...
- 在Ubuntu上安装Hbase
1.下载hbase2.0.5 解压缩并改名为hbase目录,放到/usr/local下(注意权限) sudo mv ~/hbase-2.0.5 /usr/local/hbase 2.修改目录所有者 / ...
- MYSQL join 优化 --JOIN优化实践之快速匹配
MySQL的JOIN(四):JOIN优化实践之快速匹配 优化原则:小表驱动大表,被驱动表建立索引有效,驱动表建立索引基本无效果.A left join B :A是驱动表,B是被驱动表:A right ...
- python-day38(正式学习)
目录 线程 线程开启的两种方式 1 2 子线程和子进程的创建速度 子线程共享资源 线程的join方法 守护线程 线程其他用法 线程 线程开启的两种方式 1 from threading import ...
- python_0基础开始_day04
第四节 一.列表 list 数据类型之一,存储大量的,不同类型的数据 列表中只要用逗号隔开的就是一个元素 有序可变的. 1.1列表的索引 列表和字符串一样也拥有索引,但是列表可以修改: lst = [ ...
- python-day9(正式学习)
目录 深浅拷贝 拷贝 浅拷贝 深拷贝 异常处理 什么是异常 语法错误 逻辑错误 异常的种类 常用的异常 其他异常 异常处理 提前预防 事后预防 抛出异常(基本没用) 断言(调试用,现在基本上没用) 文 ...
- 15、R语言聚类树的绘图原理
聚类广泛用于数据分析.去年研究了一下R语言聚类树的绘图原理.以芯片分析为例,我们来给一些样品做聚类分析.聚类的方法有很多种,我们选择Pearson距离.ward方法. 选择的样品有: "GS ...
- nginx(五)- linux下安装nginx与配置
linux系统为Centos 64位 准备目录 [root@instance-3lm099to ~]# mkdir /usr/local/nginx [root@instance-3lm099to ~ ...
- a标签的download属性
a标签加上downlaod属性后,就可完成对href属性链接文件的下载,但仅仅是限于同源文件,如果是非同源,download属性会失效. 无download属性的时候,a标签的默认行为是链接跳转进行预 ...