「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$种减肥药包含 ...
随机推荐
- sublime text 3支持GBK编码
1.安装Package Control: 按Ctrl+~打开命令行,然后复制粘贴下面这一行代码,回车确定: import urllib.request,os; pf = 'Package Contro ...
- html元素两种分类。替换元素和不可替换元素;块级元素和行内元素
根据元素本身特点来分类: 替换元素替换元素根据其标签和属性来决定元素的具体显示内容.有<img><input><textarea><select>< ...
- nodejs中引入art-template模板
使用Webstorm创建nodejs express应用时,默认使用的是jade或者ejs模板,对于不习惯这两种模板语法的人来说确实不是很方便.没关系,这里我们使用art-template模板引擎,使 ...
- 一:SpringIOC&DI
一:spring 1.spring介绍 spring负责管理项目中的所有对象,看作是项目中对象的管家. spring一站式框架: spring框架性质是属于容器性质的 容器中装什么对象就有什么功能,所 ...
- 流畅的python和cookbook学习笔记(四)
1.数字的四舍五入 对于简单的舍入运算,使用内置的 round(value, ndigits) 函数即可. round 函数返回离它最近的偶数.也就是说,对 1.5 或者 2.5 的舍入运算都会得到 ...
- Apache2.4+PHP7.3 安装及整合教程[Windows]
系统环境:Win10 64位 Apache版本:2.4.37 64位 PHP版本:7.3.1 64位 下载 安装的第一步肯定是下载了,可以直接到我的网盘(密码:18tp)下载,下载完成后将文件解压到你 ...
- SQL SEVERE 基本用法 1
知识点: 数据库的存储结构分为逻辑存储结构和物理存储结构两种, 其中逻辑存储结构指是由那些信息组成,物理存储结构是指如何在磁盘上存储数据库文件的. 数据库文件由数据文件和事务日志文件组成,一个数据库至 ...
- Java温故而知新(2)多线程详解
多线程指的是在单个程序中可以同时运行多个同的线程执行不同的任务.线程是程序内的顺序控制流,只能使用分配给序的资源和环境. 一.线程与进程的区别 多个进程的内部数据和状态都是完全独立的,而多线程 ...
- hdu 4055 Number String(递推DP)
给一个只含‘I','D','?'三种字符的字符串,I表示当前数字大于前面的数字,D表示当前的数字小于前面一位的数字,?表示当前位既可以小于又可以大于. 问1~n的排列中有多少个满足该字符串. http ...
- BZOJ4698: Sdoi2008 Sandy的卡片(二分 hash)
题意 题目链接 Sol 用什么后缀数组啊 直接差分之后 二分+hash找最长公共子串就赢了啊... 时间复杂度:\(O(nlogn)\)(不过我写的是两个log..反正也能过) // luogu-ju ...