「LG4782 模板 2-SAT 问题」
来学\(2\)-\(sat\)了
这个东西确实不难
这个算法就是给你一堆\(bool\)变量\(x_1,x_2...x_n\),之后给你一些限制
限制的形式就是给你一对\((u,o1,v,o2)\)
让\(x_u=o1\)或者\(x_v=o2\)
之后满足所有限制
这个东西非常容易就能抽象成一个图论模型
我们把每个\(x_i\)拆成\(i\)和\(i'\)两个点,分别表示真和假
我们对于每一个限制,连出去一些边,边\((x,y)\)的含义是选择了\(x\)就必须选择\(y\)
举个例子吧
如果一条限制是
\]
那么\(u\)向\(v\)连边,表示\(x_u=1\)的时候\(x_v\)也得等于\(1\)
同时\(v'\)向\(u'\)连边,表示\(x_v=0\)的时候\(x_u\)只能等于\(0\)
这样的话如果从\(i\)能通过这种边一路推到\(i'\)就表示让\(x_i=1\)的话就必须让\(x_i=0\)这显然不合理
于是就能判断无解情况了,一个\(tarjan\)下去找一个强联通分量
还有些题目需要我们构造出一组可行解
其实就是输出\(col[i]<col[i']\)
\(col[i]\)就是这个点所属强联通分量的编号
看起来很神奇,其实是这样的
我们考虑把\(tarjan\)缩完点的图建出来,发现我们肯定是尽量优先选择那些拓扑序较大的,因为优先选择拓扑序较大的可以使得必须选择的点少一些
由于\(tarjan\)的性质\(col\)正好是反向拓扑序,于是如果\(i\)的\(col\)较小,也就是拓扑序较大,那就优先选择\(x_i=1\)
没了
#include<cstdio>
#include<cstring>
#include<iostream>
#define min(a,b) ((a)<(b)?(a):(b))
#define re register
#define maxn 2000005
inline int read() {
	char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
struct E{int v,nxt;}e[maxn];
int n,num,cnt,p,mid,top,m;
int col[maxn],head[maxn],dfn[maxn],low[maxn],st[maxn],f[maxn];
inline void add(int x,int y) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
void tarjan(int x) {
	dfn[x]=low[x]=++cnt;st[++top]=x;f[x]=1;
	for(re int i=head[x];i;i=e[i].nxt)
	if(!dfn[e[i].v]) tarjan(e[i].v),low[x]=min(low[x],low[e[i].v]);
		else if(f[e[i].v]) low[x]=min(low[x],dfn[e[i].v]);
	if(low[x]!=dfn[x]) return;++p;
	do{mid=st[top--];f[mid]=0,col[mid]=p;}while(mid!=x);
}
int main() {
	n=read(),m=read();
	int x,y,o1,o2;
	for(re int i=1;i<=m;i++) {
		x=read(),o1=read(),y=read(),o2=read();
		if(o1==1) {if(!o2) add(x+n,y+n);else add(x+n,y);}
		if(o1==0) {if(!o2) add(x,y+n);else add(x,y);}
		std::swap(x,y),std::swap(o1,o2);
		if(o1==1) {if(!o2) add(x+n,y+n);else add(x+n,y);}
		if(o1==0) {if(!o2) add(x,y+n);else add(x,y);}
	}
	for(re int i=1;i<=n+n;i++) if(!dfn[i]) tarjan(i);
	for(re int i=1;i<=n;i++) if(col[i]==col[i+n]) {puts("IMPOSSIBLE");return 0;}
	puts("POSSIBLE");
	for(re int i=1;i<=n;i++) printf("%d ",col[i]<col[i+n]);
	return 0;
}
「LG4782 模板 2-SAT 问题」的更多相关文章
- [Luogu 3701] 「伪模板」主席树
		[Luogu 3701] 「伪模板」主席树 这是一道网络流,不是主席树,不是什么数据结构,而是网络流. 题目背景及描述都非常的暴力,以至于 Capella 在做此题的过程中不禁感到生命流逝. S 向 ... 
- 「雅礼集训 2017 Day2」解题报告
		「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ... 
- SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」
		有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1-Spr ... 
- 「Mobile Testing Summit China 2016」 中国移动互联网测试大会-议题征集
		时至北京盛夏,一场由 TesterHome 主办的关于移动互联网测试技术的盛会正在紧锣密鼓的筹备中.只要你关注软件质量,热爱测试,期待学习,都欢迎你加入这次移动测试技术大会中和我们一起分享经验.探讨话 ... 
- 【翻译】西川善司「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,前篇(2)
		Lighting和Shading(2)镜面反射的控制和模拟次级表面散射技术 http://www.4gamer.net/games/216/G021678/20140703095/index_2.ht ... 
- 「七天自制PHP框架」第二天:模型与数据库
		往期回顾:「七天自制PHP框架」第一天:路由与控制器,点击此处 什么是模型? 我们的WEB系统一定会和各种数据打交道,实际开发过程中,往往一个类对应了关系数据库的一张或多张数据表,这里就会出现两个问题 ... 
- 「七天自制PHP框架」第三天:PHP实现的设计模式
		往期回顾:「七天自制PHP框架」第二天:模型与数据库,点击此处 原文地址:http://www.cnblogs.com/sweng/p/6624845.html,欢迎关注:编程老头 为什么要使用设计模 ... 
- 「七天自制PHP框架」第四天:模型关联
		往期回顾:「七天自制PHP框架」第三天:PHP实现的设计模式,点击此处 原文地址:http://www.cnblogs.com/sweng/p/6624845.html,欢迎关注:编程老头 前阵子在网 ... 
- LOJ_6045_「雅礼集训 2017 Day8」价 _最小割
		LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ... 
随机推荐
- 第八章使用java实现面向对象-File I/O
			java.io.File类用于表示文件(目录) File类只用于表示文件(目录)的信息(名称.大小等),不能用于文件内容的访问 RandomAccessFile java提供的对文件内容的访问,既可以 ... 
- ODBC, OLEDB, ADO, ADO.NET
			在SSIS中,选择Connction Manager时,有很多的类型.其中会发现如下4个连接类型ODBC, OLEDB, ADO, ADO.NET.这4个东东到底是什么,他们有什么关联,什么区别,如何 ... 
- unity 中 protobuff 的用法 一句话攻略
			(一)unity 添加 pb 的 dll 支持.1,从GitHub上下载protobuf源码 (源码链接:https://github.com/google/protobuf),找到 csharp 分 ... 
- MVC中FileResult 返回类型返回Excel
			公司中以前写的导出有问题.原来使用的XML格式字符串拼接然后转化成流输出 action public FileResult ExportJobFair() { try { string name = ... 
- document文档流详解
			html页面下载完默认会打开一个文档流document对象(调用document.open,此时浏览器标题左边会显示加载中图标),开始从上往下渲染内容,渲染完成调用document.close关闭渲染 ... 
- golang学习之select用法
			早期的select函数是用来监控一系列的文件句柄,一旦其中一个文件句柄发生IO操作,该select调用就会被返回.golang在语言级别直接支持select,用于处理异步IO问题. select用法同 ... 
- 修改npm包管理器的registry为淘宝镜像(npm.taobao.org)<转>
			起因 安装了node,安装了npm之后,官方的源实在是 太慢了! 看了看淘宝的npm镜像, http://npm.taobao.org/ 竟然说让我再下载一个cnpm,要不然就每次都得install ... 
- Linux中的叹号命令
			在shell环境下操作,需要积累点快捷输入的小技巧: 最常用的技巧恐怕就是Tab自动补全以及上方向键来回退上几条历史命令了,这些对于csh,bash,ksh,zsh都适用. 最近还找到一种快速回退上一 ... 
- JavaMail 邮件发送
			jar包部署 /** * 通过SMTP进行邮件集成 */ public class CmpSendMail { // 邮件发送服务器主机 private final static String HOS ... 
- lintcode题目记录4
			Russian Doll Envelopes Largest Divisible Subset Two Sum - Input array is sorted Russian Doll ... 
