一、问题描述

以你咕的模板题为例

题目描述

有\(n\)个布尔变量\(x_1\)~\(x_n\),另有\(m\)个需要满足的条件,每个条件的形式都是“\(x_i\)为true/false或\(x_j\)为true/false”。

比如“\(x_1\)为真或\(x_3\)为假”、“\(x_7\)为假或\(x_2\)为假”。

2-SAT 问题的目标是给每个变量赋值使得所有条件得到满足。

二、逻辑关系

这里不用太过专业的符号来说明逻辑关系,仅仅是感性说明(没错就是我菜)

设条件为大写字母A,B,非A,非B只条件的另一种取值

A或者B 等价于 非A则B 和 非B则A

注意到后面两个要求似乎有蜜汁对称性,而且它们都是有向的

根据后一句话,我们借助并查集扩展域的思想,把一个点的两个取值拆开,进行建图

三、建图

这里就画图举例说明吧

给出这样三个条件\((1,1)\)或\((2,1)\),\((2,1)\)或\((3,1)\),\((2,0)\)或(3,1)$

\((x,y)\)表示\(x\)需要取值\(y\)

我们把点\(x\)取值\(0\)的点编号\(x\),取值\(1\)的点编号\(x+n\)

我们可以建出如下的图

有向边\((u,v)\)表示如果\(u\)选,\(v\)一定选

很显然这是有解的,我们可以去\(1,2,3\)等点集

怎么样才会无解呢?

如果一个点的出边的点构成的集合中又出现了它自己?这样可以不选它而选另一个值啊

如果这个集合出现了另一个值呢?

好吧,这里的无解其实就是综合一下,选它的同时要选它的另一个值,选它的另一个值同时要选它

等价于两者在有向图中处于同一个环中

这样我们就可以通过tarjan求环来判断有解性了

四、构造合法方案

如果一个点没有伸出去的边,就代表它不约束别人,我们可以随便选择选或不选它

设\(cho[]\),若\(cho[x]==0\)则代表我们选择了它,否则我们没有选择它

优先选择出度为0的点

我们可以在缩点后的图中反向建图,然后做拓扑排序

注意我们选择一个点后,要把它对应的点置不选

事实上,我们也可以没必要做这么麻烦

dfs遍历的DAG图的序列反过来其实就是反向建边的拓扑序

在tarjan中先做的点的编号就是反向建边拓扑序

那么我们直接比编号大小进行赋值就可以啦

五、参考代码

#include <cstdio>
int min(int x,int y){return x<y?x:y;}
const int N=2e6+10;
int head[N],to[N<<1],Next[N<<1],cnt,n,m;
void add(int u,int v)
{
to[++cnt]=v;Next[cnt]=head[u];head[u]=cnt;
}
void init()
{
scanf("%d%d",&n,&m);
for(int i,a,j,b,k=1;k<=m;k++)
{
scanf("%d%d%d%d",&i,&a,&j,&b);
add(i+(1-a)*n,j+b*n),add(j+(1-b)*n,i+a*n);
}
}
int dfn[N],low[N],in[N],s[N],ha[N],tot,dfs_clock,n_;
void tarjan(int now)
{
dfn[now]=low[now]=++dfs_clock;
s[++tot]=now;
in[now]=1;
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(!dfn[v])
{
tarjan(v);
low[now]=min(low[now],low[v]);
}
else if(in[v])
low[now]=min(low[now],dfn[v]);
}
if(low[now]==dfn[now])
{
int k;++n_;
do
{
k=s[tot--];
ha[k]=n_;
in[k]=0;
}while(k!=now);
}
}
void work()
{
for(int i=1;i<=n<<1;i++) if(!dfn[i]) tarjan(i);
for(int i=1;i<=n;i++)
if(ha[i]==ha[i+n])
{
printf("IMPOSSIBLE\n");
return;
}
printf("POSSIBLE\n");
for(int i=1;i<=n;i++)
printf("%d ",ha[i]>ha[i+n]);
}
int main()
{
init();
work();
return 0;
}

2018.9.1

2-sat 学习笔记的更多相关文章

  1. <老友记>学习笔记

    这是六个人的故事,从不服输而又有强烈控制欲的monica,未经世事的千金大小姐rachel,正直又专情的ross,幽默风趣的chandle,古怪迷人的phoebe,花心天真的joey——六个好友之间的 ...

  2. OGG学习笔记02-单向复制配置实例

    OGG学习笔记02-单向复制配置实例 实验环境: 源端:192.168.1.30,Oracle 10.2.0.5 单实例 目标端:192.168.1.31,Oracle 10.2.0.5 单实例 1. ...

  3. python数据分析入门学习笔记

    学习利用python进行数据分析的笔记&下星期二内部交流会要讲的内容,一并分享给大家.博主粗心大意,有什么不对的地方欢迎指正~还有许多尚待完善的地方,待我一边学习一边完善~ 前言:各种和数据分 ...

  4. 【MarkMark学习笔记学习笔记】javascript/js 学习笔记

    1.0, 概述.JavaScript是ECMAScript的实现之一 2.0,在HTML中使用JavaScript. 2.1 3.0,基本概念 3.1,ECMAScript中的一切(变量,函数名,操作 ...

  5. Linux 学习笔记之超详细基础linux命令 Part 13

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 12---------------- ...

  6. Linux 学习笔记之超详细基础linux命令 Part 8

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 7----------------- ...

  7. Deep learning with Python 学习笔记(5)

    本节讲深度学习用于文本和序列 用于处理序列的两种基本的深度学习算法分别是循环神经网络(recurrent neural network)和一维卷积神经网络(1D convnet) 与其他所有神经网络一 ...

  8. 【Redis】命令学习笔记——字符串(String)(23个超全字典版)

    Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). 本篇基于redis 4.0.11版本,学习字符串( ...

  9. programming-languages学习笔记--第3部分

    programming-languages学习笔记–第3部分 */--> pre.src {background-color: #292b2e; color: #b2b2b2;} pre.src ...

  10. 学习笔记 - 2sat

    学习笔记 - 2sat 决定重新启用Markdown--只是因为它支持MathJax数学公式 noip考完,既轻松又无奈,回来慢慢填坑 这篇博客也是拖了好久,通过kuangbin的博客才弄懂2-sat ...

随机推荐

  1. SpringBoot注入Mapper提示Could not autowire. No beans of 'xxxMapper' type found错误

    通过用Mabatis的逆向工程生成的Entity和Mapper.在Service层注入的时候一直提示Could not autowire. No beans of 'xxxMapper' type f ...

  2. Lucene实战

    导包

  3. [C#]常用开源项目

    [转][C#]常用开源项目 本文来自:http://www.cnblogs.com/sunxuchu/p/6047589.html Json.NET http://www.newtonsoft.com ...

  4. C语言字符篇(一)字符串转换函数

      #include <stdlib.h>   double atof(const char *nptr);  将字符串转换成双精度浮点数 int atoi(const char *npt ...

  5. 单源次短路径:poj:3255-Roadblocks

    Roadblocks Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 17521 Accepted: 6167 Descripti ...

  6. CSS3---混合模式

    概念 CSS3混合模式(  CSS Blend Modes  )是CSS3新增的一个魔法特性,可以允许多个背景或多个元素进行混合,类似于Photoshop的图层混合模式 CSS3混合模式属性一览 ba ...

  7. 《Cracking the Coding Interview》——第13章:C和C++——题目3

    2014-04-25 19:42 题目:C++中虚函数的工作原理? 解法:虚函数表?细节呢?要是懂汇编我就能钻的再深点了.我试着写了点测大小.打印指针地址之类的代码,能起点管中窥豹的作用,从编译器的外 ...

  8. 《Cracking the Coding Interview》——第4章:树和图——题目5

    2014-03-19 04:11 题目:设计算法检查一棵二叉树是否为二叉搜索树. 解法:既然是二叉搜索树,也就是说左子树所有节点都小于根,右子树所有节点都大于根.如果你真的全都检查的话,那就做了很多重 ...

  9. USACO Section1.3 Mixing Milk 解题报告

    milk解题报告 —— icedream61 博客园(转载请注明出处)----------------------------------------------------------------- ...

  10. USACO Section1.1 Friday the Thirteenth 解题报告

    friday解题报告 —— icedream61 博客园(转载请注明出处) -------------------------------------------------------------- ...