题目

来学\(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,0,v,1)
\]

那么\(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 问题」的更多相关文章

  1. [Luogu 3701] 「伪模板」主席树

    [Luogu 3701] 「伪模板」主席树 这是一道网络流,不是主席树,不是什么数据结构,而是网络流. 题目背景及描述都非常的暴力,以至于 Capella 在做此题的过程中不禁感到生命流逝. S 向 ...

  2. 「雅礼集训 2017 Day2」解题报告

    「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...

  3. SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」

    有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1-Spr ...

  4. 「Mobile Testing Summit China 2016」 中国移动互联网测试大会-议题征集

    时至北京盛夏,一场由 TesterHome 主办的关于移动互联网测试技术的盛会正在紧锣密鼓的筹备中.只要你关注软件质量,热爱测试,期待学习,都欢迎你加入这次移动测试技术大会中和我们一起分享经验.探讨话 ...

  5. 【翻译】西川善司「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,前篇(2)

    Lighting和Shading(2)镜面反射的控制和模拟次级表面散射技术 http://www.4gamer.net/games/216/G021678/20140703095/index_2.ht ...

  6. 「七天自制PHP框架」第二天:模型与数据库

    往期回顾:「七天自制PHP框架」第一天:路由与控制器,点击此处 什么是模型? 我们的WEB系统一定会和各种数据打交道,实际开发过程中,往往一个类对应了关系数据库的一张或多张数据表,这里就会出现两个问题 ...

  7. 「七天自制PHP框架」第三天:PHP实现的设计模式

    往期回顾:「七天自制PHP框架」第二天:模型与数据库,点击此处 原文地址:http://www.cnblogs.com/sweng/p/6624845.html,欢迎关注:编程老头 为什么要使用设计模 ...

  8. 「七天自制PHP框架」第四天:模型关联

    往期回顾:「七天自制PHP框架」第三天:PHP实现的设计模式,点击此处 原文地址:http://www.cnblogs.com/sweng/p/6624845.html,欢迎关注:编程老头 前阵子在网 ...

  9. LOJ_6045_「雅礼集训 2017 Day8」价 _最小割

    LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ...

随机推荐

  1. 利用WebBrowser控件实现百度自动搜索

    (1)新建一个MFC对话框项目 (2)对话框中添加WebBrower控件,添加方法:点击菜单栏工具->选择工具箱项->在弹出的选择工具箱项对话框选择COM组件->Microsoft  ...

  2. MySql数据库与JDBC编程二

    DML语法语句:主要操作数据表中的数据,完成插入新数据,修改已有数据,删除不要的数据的任务 1,insert into 语句 用于向指定表插入数据,一次只能插入一条记录:insert into tab ...

  3. 006.ASP.NET MVC ActionResults说明

    原文:http://rachelappel.com/asp.net-mvc-actiohttp://i.cnblogs.com/EditPosts.aspx?postid=3857238&up ...

  4. 2018-12-25 课堂笔记&面试题

    面试题一.Java中,八大基本数据类型有哪些?答:数值型:整型(byte.short.int.long)浮点型(float.double)非数值型:布尔类型(boolean)字符型(char).注意: ...

  5. pyhton中list的基本操作

    list:可以按规则,按顺序,存取大量数据 1.增 append() 在列表尾部追加元素 insert() 按照列表索引添加元素 extend() 迭代添加元素,一次添加多个元素 2.删 pop() ...

  6. 浅谈PVC塑料配方计算软件的设计

    1, 配方设计与配方计算 题目是配方计算,不是配方设计,设计是需要有深厚的塑料知识才可以做的,即生产什么塑料产品,需要放各种原料是什么,各自比较是多少,遇到什么情况下就要多放什么,少放什么.配方设计不 ...

  7. Thread调用SaveFileDialog

    public void ThreadSaveFileDialog(string sourceFileName) { Thread importThread = new Thread(new Param ...

  8. java word转pdf 工具类

    package com.elitel.hljhr.comm.web.main.controller; import java.io.File; import java.io.FileOutputStr ...

  9. JAVA程序员常用开发工具

    1.JDK (Java Development Kit)Java开发工具集 SUN的Java不仅提了一个丰富的语言和运行环境,而且还提了一个免费的Java开发工具集(JDK).开发人员和最终用户可以利 ...

  10. 使用Powershell 管理 Windows 2012 hyper-v复制

    HyperV复制相关命令 Suspend-VMReplication Suspends replication of a virtual machine. 暂停复制虚拟机. Resume-VMRepl ...