P4782 【模板】2-SAT 问题

题意

题目背景

\(2-SAT\)问题模板

题目描述

有\(n\)个布尔变量\(x_1\sim x_n\),另有\(m\)个需要满足的条件,每个条件的形式都是“\(x_i\)为\(true/false\)或\(x_j\)为\(true/false\)”。比如“\(x_1\)为真或\(x_3\)为假”、“\(x_7\)为假或\(x_2\)为假”。\(2-SAT\)问题的目标是给每个变量赋值使得所有条件得到满足。

输入输出格式

输入格式:

第一行两个整数\(n\)和\(m\),意义如题面所述。

接下来\(m\)行每行\(4\)个整数\(i\ a\ j\ b\),表示“\(x_i\)为\(a\)或\(x_j\)为\(b\)”\((a,b\in \{ 0,1\} )\)

输出格式:

如无解,输出"IMPOSSIBLE"(不带引号); 否则输出"POSSIBLE"(不带引号),下一行\(n\)个整数\(x_1\sim x_n(x_i\in \{ 0,1\} )\),表示构造出的解。

输入输出样例

输入样例#1:

3 1
1 1 3 0

输出样例#1:

POSSIBLE
0 0 0

思路

快学\(2-SAT\),这样你就可以做[NOI2017]游戏这道水题了。 --huyufeifei

\(2-SAT\)问题是我很喜欢的一类问题,一是因为它使用了我很喜欢的\(Tarjan\)算法
,二是它使用逻辑判断的方式实现的算法,这也是很使我喜欢的。

对于每一个\(x_i\)我们建两个点,编号为\(i\)和\(i+n\),\(i\)表示\(x_i=1\)的情况,\(i+n\)表示\(x_i=0\)的情况。接下来考虑对于每一对逻辑关系建边。在这里,为了问题的普适性,我们不止考虑题目列出的条件,来试着考虑更多的情况。

  • \(a\)为真:建立一条边\((a+n,a)\),表示如果\(a\)为假,则\(a\)为真。这样就可以最终推得\(a\)为真的情况。
  • 如果\(a\)为真,则\(b\)为假:建立两条边:\((a,b+n),(b,a+n)\)。
  • \(a\)为真与\(b\)为假至少满足一个:建立两条边:\((a+n,b+n),(b,a)\)。
  • \(a\)为真与\(b\)为假不能同时满足:建立两条边:\((a,b),(b+n,a+n)\)。

还有很多的情况没有枚举,不过它们与上述内容形似,在这里就不做列举了。

接下来怎么办呢?根据我们连边的方式,不难发现边的意义为推导出,也就是说,如果\(a\)能通过某些路径到达\(b\),这表示的意义就是\(a\)能通过某些条件推导出\(b\),那么如果我们让\(a\)满足,\(b\)就一定要被满足。如果\(a,b\)能够互达,就说明这两者要么同时被满足,要么同时不被满足。

不难想出,有且仅有一种情况无解:\(a\)与\(a+n\)可以互达,也就是两个互相矛盾的条件可以互相推导出。使用\(Tarjan\)缩点,这样可以快速求出任意两点是否可以互相到达,也就可以判断出解的存在性。

如何决定各个变量的取值呢?如果能从\(a\)推导出\(a+n\),我们显然不能选择\(a\),而只能选择\(a+n\)。所以对于同一个变量的两个取值,我们要检查其是否有推导的关系。根据\(Tarjan\)算法的特性,如果\(a\)能到达\(b\)且\(a,b\)不在同一缩出的点中,那么\(b\)缩点之后所在点的编号一定小于\(a\)。如果\(a\)不能到达\(b\),那么两者的缩点编号不好判断。当然,既然只需要得出任意一组解,对于每一对\((a,a+n)\),我们就输出其缩点编号小的即可。

AC代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e6+5;
int n,m,tot,dfn[MAXN],low[MAXN];
int cnt,top[MAXN],to[MAXN],nex[MAXN];
int js,bel[MAXN];
bool vis[MAXN];
stack<int>S;
int read()
{int re=0;char ch=getchar();while(!isdigit(ch)) ch=getchar();while(isdigit(ch)) re=(re<<3)+(re<<1)+ch-'0',ch=getchar();return re;
}
void add_edge(int x,int y){to[++cnt]=y,nex[cnt]=top[x],top[x]=cnt;}
void tarjan(int now)
{dfn[now]=low[now]=++tot,vis[now]=true;S.push(now);for(int i=top[now];i;i=nex[i])if(!dfn[to[i]]) tarjan(to[i]),low[now]=min(low[now],low[to[i]]);else if(vis[to[i]]) low[now]=min(low[now],dfn[to[i]]);if(dfn[now]==low[now]){bel[now]=++js,vis[now]=false;while(S.top()!=now) bel[S.top()]=js,vis[S.top()]=false,S.pop();S.pop();}
}
int main()
{n=read(),m=read();while(m--){int x=read(),xx=read(),y=read(),yy=read();if(xx&&yy) add_edge(x+n,y),add_edge(y+n,x);else if(xx&&!yy) add_edge(x+n,y+n),add_edge(y,x);else if(!xx&&yy) add_edge(x,y),add_edge(y+n,x+n);else if(!xx&&!yy) add_edge(x,y+n),add_edge(y,x+n);}for(int i=1;i<=(n<<1);i++) if(!dfn[i]) tarjan(i);for(int i=1;i<=n;i++)if(bel[i]==bel[i+n]){printf("IMPOSSIBLE");return 0;}puts("POSSIBLE");for(int i=1;i<=n;i++) printf("%d ",bel[i]<bel[i+n]);return 0;
}

转载于:https://www.cnblogs.com/coder-Uranus/p/9893511.html

Luogu P4782 【模板】2-SAT 问题(2-SAT)相关推荐

  1. SAT考试之SAT词汇记忆4步走

    SAT考试分为两种.一个是SATI,又称推理检验(ReasoningTest,包括阅读.写作和数学;SATII,又称专项检验(SubjectTests,目前,SATII共有20门考试,分别为英文写作. ...

  2. [Luogu] P3376 模板-网络流-最大流

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...

  3. SAT OG 写作辅导:良知是一种比金钱名望和权力更有力的激励?

    SAT是由美国大学委员会(College Board主办,SAT成绩是世界各国高中生申请美国名校学习及奖学金的重要参考.总分2400分:分为阅读.写作.数学.理事会(College Board.ETS ...

  4. Sat格式文件详解翻译

    SAT Save File Format 7.0(Sat文件存储格式7.0) 译者:Mrzhu007 日期:2018年04月13日 博客地址:金色世界 ACIS can store modeling ...

  5. MIT录取不再看SAT科目成绩:曾是华裔传统优势,数学等学科测验更是中国留学生强项...

    晓查 发自 凹非寺  量子位 报道 | 公众号 QbitAI 美国麻省理工学院今天在招生网站上宣布,决定不再考虑将SAT科目考试作为录取过程的一部分. 这一决定从2020~2021学年开始生效. SA ...

  6. 欧文分校计算机新sat多少分录取,加州大学欧文分校SAT成绩要求是多少?

    加州大学欧文分校对于SAT成绩的要求是多少?现在申请美国本科,很多都是需要同学们提供sat成绩的额,下面托普仕留学老师为大家介绍SAT多少分才能申请加州大学欧文分校?同学们在申请之前要多注意院校信息. ...

  7. luogu P3379 【模板】最近公共祖先(LCA)

    lca最近公共祖先,是指两个点最近的祖先节点:求lca我知道的有三种倍增, st表,tarjan,我要介绍的是倍增,我才不会告诉你我只会这一个. 话说我学lca可真的路途曲折,在qbxt,lcy da ...

  8. 欧文分校计算机新sat多少分录取,加州大学欧文分校SAT成绩要求

    下面为大家介绍的是加州大学欧文分校University of California Irvine的SAT成绩要求.加州大学欧文分校University of California Irvine是美国加 ...

  9. Games202 Lecture3-4之SAT: Summed Area Table

    SAT: Summed Area Table 一维 二维 分析 一种可以准确进行范围查询的方式. 数据结构: Summed Area Table (SAT) 算法:prefix sum 前缀和 一维 ...

最新文章

  1. Nginx+tomcat负载均衡session问题解决
  2. java字符串 大括号_string.format格式化字符串中转义大括号“{}”
  3. SQL2000 MD5加密
  4. LeetCode 466. 统计重复个数(循环节)
  5. 学好JAVA保终身_JAVA IO 学习
  6. 【python工具】获取linux和windows系统指定接口的IP地址
  7. 在线教育平台签约电子化:借电子印章提速控本、服务师生
  8. [20210425]什么?号称世界上最难的数独居然没有坚持到2秒
  9. 微信好友检测助手App
  10. 全国所有省份行政区域名标准(全国省份2字母拼音缩写标准参考)
  11. web调用IC卡读卡器开发第七章--NFC标签NDEF数据
  12. 收款码三合一制作微信小程序源码下载多模板选择
  13. webp的js插件_Vuejs webp图片支持,插件开发过程~ - 简书
  14. qt、adb、小米屏幕滑动demo
  15. Python图像增强(翻转和旋转)
  16. 科创人·知乎CTO李大海:技术服务内容、商业化依赖内容,曾被「呵呵」难到挠头
  17. Theme Studio(主题工作室)
  18. MyEclipse2014用外部的浏览器运行web项目
  19. TensorFlow下用自己的数据训练Fater-RCNN
  20. linux socket错误提示errno分析

热门文章

  1. Windows环境下配置环境变量
  2. oracle SQL 命令行(二.视图)
  3. 图片上传成功但是图片显示不出来_小程序上传图片到腾讯云
  4. 在计算机上创建一个本地用户账户,在工作组中,默认时每台Windows计算机的( )能够在本地计算机的SAM数据库中创建并管理本地用户账户。...
  5. linux访问网页元素,Linux_DOM和JAVASCRIPT访问页面上的元素,访问方法:getElementById() - phpStudy...
  6. 浅析企业建站都需要了解哪些基础内容?
  7. android test.apk,app-debug.apk和app-debug-androidTest.apk在安装macaca-android模块的时候build失败...
  8. java 容器_Java容器框架学习整理
  9. jfinal怎么连接oracle,如何用Jfinal连接多个数据库
  10. 在jupyter notebook中attr1参数的作用_PID控制中P、I、D参数的作用究竟是什么?