1. 2-SAT

1.1. 介绍

对于一些节点,每个节点存在两个状态(非 \(0\) 即 \(1\)),我们给出一些如下类型的限制条件:

  • 节点 \(i\) 状态为 \(1/0\)。
  • 若节点 \(i\) 状态为 \(1/0\),那么节点 \(j\) 状态为 \(1/0\)。
  • 节点 \(i,j\ (i\not=j)\) 至少有一个为 \(1/0\)。

2-SAT 算法用于解决类似的问题,每个节点最多只能有两种状态。

我们用有向图表示节点状态之间的递推关系,我们设 \(p_i\) 表示节点 \(i\) 状态为真,我们将上述限制条件写为表达式并写为“若 \(p\) ,则 \(q\)”的形式,便于用有向图表示它们的关系:

  • \(p_i\):若 \(\lnot p_i\),则 \(p_i\)。
  • \(\lnot p_i\):若 \(p_i\),则 \(\lnot p_i\)。
  • \(p_i\lor p_j\):若 \(\lnot p_i\) 则 \(p_j\);若 \(\lnot p_j\) 则 \(p_i\)。
  • \(\lnot p_i\lor\lnot p_j\):若 \(p_i\) 则 \(\lnot p_j\);若 \(p_j\) 则 \(\lnot p_i\)。
  • \(\lnot p_i\lor p_j\):若 \(p_i\) 则 \(p_j\);若 \(\lnot p_j\) 则 \(\lnot p_i\)。

若有 \(p\Rightarrow q\),并且 \(p,q\) 相互矛盾,则 \(p\) 一定为假。

更进一步地,若有 \(p\Leftrightarrow q\),并且 \(p,q\) 相互矛盾,则此限制条件下,无解。

考虑无解的情况在有向图中的表现形式,即两个矛盾状态在图中处于同一个强连通分量中,我们考虑用 Tarjan 算法进行缩点。

对于一种可行方案则在 \(p_i,\lnot p_i\) 两个状态点中选择拓扑序更小的即可,用 Tarjan 后可省去拓扑排序过程,详见我其他博客。

1.2. 例题

\(\color{royalblue}{P4782}\)

板子题。

$\text{Code}$:
#include<bits/stdc++.h>
#define LL long long
#define UN unsigned
using namespace std;
//--------------------//
//IO
inline int rd()
{
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
//--------------------//
const int N=2e6+5; int n,m;
//--------------------//
struct Edge
{
int to,nex;
}edge[N];
int tot,head[N];
void add(int from,int to)
{
edge[++tot]={to,head[from]};
head[from]=tot;
return;
} int dcnt,dfn[N],low[N];
int sccnt,scc[N];
int stop,sta[N];
bool stv[N]; void Tarjan(int now)
{
low[now]=dfn[now]=++dcnt;
sta[++stop]=now,stv[now]=true;
for(int to,i=head[now];i;i=edge[i].nex)
{
to=edge[i].to;
if(!dfn[to])
{
Tarjan(to);
low[now]=min(low[now],low[to]);
}
else if(stv[to])
low[now]=min(low[now],dfn[to]);
}
if(low[now]==dfn[now])
{
scc[now]=++sccnt;
stv[now]=false;
while(sta[stop]!=now)
{
scc[sta[stop]]=sccnt;
stv[sta[stop]]=false;
stop--;
}
stop--;
}
return;
}
//--------------------//
int main()
{
scanf("%d%d",&n,&m);
for(int a,x,b,y,i=1;i<=m;i++)
{
scanf("%d%d%d%d",&a,&x,&b,&y);
add(a+(!x)*n,b+y*n);
add(b+(!y)*n,a+x*n);
}
for(int i=1;i<=2*n;i++)
if(!dfn[i])
Tarjan(i);
for(int i=1;i<=n;i++)
if(scc[i]==scc[i+n])
{
printf("IMPOSSIBLE\n");
return 0;
}
printf("POSSIBLE\n");
for(int i=1;i<=n;i++)
if(scc[i]<scc[i+n])
printf("0 ");
else
printf("1 ");
return 0;
}

「Note」图论方向 - 图论进阶的更多相关文章

  1. 「NOTE」常系数齐次线性递推

    要不是考到了,我还没发现这玩意我不是很会-- # 前置 多项式取模: 矩阵快速幂. # 常系数齐次线性递推 描述的是这么一个问题,给定数列 \(c_1,c_2,\dots,c_k\) 以及数列 \(f ...

  2. 「MoreThanJava」Day 5:面向对象进阶——继承详解

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...

  3. Note -「多项式」基础模板(FFT/NTT/多模 NTT)光速入门

      进阶篇戳这里. 目录 何为「多项式」 基本概念 系数表示法 & 点值表示法 傅里叶(Fourier)变换 概述 前置知识 - 复数 单位根 快速傅里叶正变换(FFT) 快速傅里叶逆变换(I ...

  4. 「MoreThanJava」Day 6:面向对象进阶——多态

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...

  5. LoibreOJ 2042. 「CQOI2016」不同的最小割 最小割树 Gomory-Hu tree

    2042. 「CQOI2016」不同的最小割 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  6. 「Sqlserver」数据分析师有理由爱Sqlserver之九-无利益关系推荐Sqlserver书单

    在前面系列文章的讲述下,部分读者有兴趣进入Sqlserver的世界的话,笔者不太可能在自媒体的载体上给予全方位的带领,最合适的方式是通过系统的书籍来学习,此篇给大家梳理下笔者曾经看过的自觉不错值得推荐 ...

  7. 《Offer一箩筐》一份高质量「简历」撰写指南,望打扰!!

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」. 如果觉得 「不错」 的朋友,欢迎 「关注 + 留言 + 分享」,文末有完整的获取链接,您的支持是我前进的最大的动力! Hi~ 这里是 ...

  8. 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management

    写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...

  9. 「2013-9-5」Configure WingIDE for better display of East Asian Glyphs

    很久没写软件配置相关的博客了.这次对于 WingIDE 在 Windows 下的字体配置,折腾了好一阵子,略曲折,也反映了「不清楚原理和背景的情况下,盲人摸象的效率低下是必然」这条放之四海而皆准的赤果 ...

  10. 一个「学渣」从零开始的Web前端自学之路

    从 13 年专科毕业开始,一路跌跌撞撞走了很多弯路,做过餐厅服务员,进过工厂干过流水线,做过客服,干过电话销售可以说经历相当的“丰富”. 最后的机缘巧合下,走上了前端开发之路,作为一个非计算机专业且低 ...

随机推荐

  1. 【Bug记录】node-sass安装失败解决方案

    node-sass 安装失败解决办法 前言 很多小伙伴在安装 node-sass 的时候都失败了,主要的原因是 node 版本和项目依赖的 node-sass 版本不匹配. 解决方案 解决方案:把项目 ...

  2. 测试驱动开发(TDD)浅析

    .wj_nav { display: inline-block; width: 100%; margin-bottom: 0.375rem } .wj_nav span { display: inli ...

  3. 一款torrent文件格式分析工具(绿色纯天然)

    点击下载 1.主界面 2.文件分析(显示文件所在分片的位置) 3.获取指定分片所在的peers服务器列表 一只会铲史的猫

  4. 密码编码学与网络安全 原理与实践(第七版)William Stallings---读书笔记(1.1-1.5)

    密码编码学与网络安全 原理与实践(第七版)William Stallings---读书笔记 第一部分 概览 第1章 计算机与网络安全概念 密码算法与协议又可分为4个主要领域: 对称加密 加密任意大小的 ...

  5. 汇编概念辨析(Intel/AT&T syntax、GAS、NASM)

    写在前面 本文并不详细介绍Intel syntax.AT&T syntax.GAS.NASM的具体内容和具体区别,而是从概念辨析的角度说明这些专有名词的含义,以便为初学者扫清疑惑.有兴趣深入了 ...

  6. EntityFrameworkCore 分页问题

    场景重现 使用 EntityFrameworkCore 连接 SQL Server 2008 执行.Skip().Take()分页查询时出现如下异常: SqlException: 'OFFSET' 附 ...

  7. DEF4Delphi-master的安装

    保姆教程 d2007的TWEBbrowser因为用的太老的IE内核.现在的浏览器上的功能呈现就卡住了. 那么DEF4Delphi效果非常好. 如何安装后成功运行.很简单.直接去:https://git ...

  8. Model Context Protocol

    MCP is an open protocol that enables AI models to securely interact with local and remote resources ...

  9. window下配置多个Git账号

    三步完成配置一台电脑下多git账号配置 1.生成密钥 git客户端安排好后,打开git Bash,生成SSH key. ssh-keygen -t rsa -C "user1111@emai ...

  10. CTF_RSA解密学习

    CTF_RSA解密学习 00X00 .先看了一边李永乐老师的视频 https://www.bilibili.com/video/av26639065/ 00X01.对称.非对称算法了解 对称算法,加解 ...