「Note」图论方向 - 图论进阶
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」图论方向 - 图论进阶的更多相关文章
- 「NOTE」常系数齐次线性递推
要不是考到了,我还没发现这玩意我不是很会-- # 前置 多项式取模: 矩阵快速幂. # 常系数齐次线性递推 描述的是这么一个问题,给定数列 \(c_1,c_2,\dots,c_k\) 以及数列 \(f ...
- 「MoreThanJava」Day 5:面向对象进阶——继承详解
「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...
- Note -「多项式」基础模板(FFT/NTT/多模 NTT)光速入门
进阶篇戳这里. 目录 何为「多项式」 基本概念 系数表示法 & 点值表示法 傅里叶(Fourier)变换 概述 前置知识 - 复数 单位根 快速傅里叶正变换(FFT) 快速傅里叶逆变换(I ...
- 「MoreThanJava」Day 6:面向对象进阶——多态
「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...
- LoibreOJ 2042. 「CQOI2016」不同的最小割 最小割树 Gomory-Hu tree
2042. 「CQOI2016」不同的最小割 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- 「Sqlserver」数据分析师有理由爱Sqlserver之九-无利益关系推荐Sqlserver书单
在前面系列文章的讲述下,部分读者有兴趣进入Sqlserver的世界的话,笔者不太可能在自媒体的载体上给予全方位的带领,最合适的方式是通过系统的书籍来学习,此篇给大家梳理下笔者曾经看过的自觉不错值得推荐 ...
- 《Offer一箩筐》一份高质量「简历」撰写指南,望打扰!!
「MoreThanJava」 宣扬的是 「学习,不止 CODE」. 如果觉得 「不错」 的朋友,欢迎 「关注 + 留言 + 分享」,文末有完整的获取链接,您的支持是我前进的最大的动力! Hi~ 这里是 ...
- 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management
写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...
- 「2013-9-5」Configure WingIDE for better display of East Asian Glyphs
很久没写软件配置相关的博客了.这次对于 WingIDE 在 Windows 下的字体配置,折腾了好一阵子,略曲折,也反映了「不清楚原理和背景的情况下,盲人摸象的效率低下是必然」这条放之四海而皆准的赤果 ...
- 一个「学渣」从零开始的Web前端自学之路
从 13 年专科毕业开始,一路跌跌撞撞走了很多弯路,做过餐厅服务员,进过工厂干过流水线,做过客服,干过电话销售可以说经历相当的“丰富”. 最后的机缘巧合下,走上了前端开发之路,作为一个非计算机专业且低 ...
随机推荐
- gorm插入报错Error 1292 (22007): Incorrect datetime value: ‘0000-00-00‘ for column ‘xxx‘ at row 1
在MySQL中,'0000-00-00 00:00:00'不是一个合法的DATETIME值.从MySQL 5.7.5开始,默认情况下不允许插入零日期或零时间值到DATETIME或 TIMESTAMP列 ...
- Vue2框架-基础
1. vue简介 什么是vue? Vue是一套用于构建用户界面的渐进式JavaScript框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,方便与第三方 ...
- 软件测试_Fiddler抓包工具
多数资料摘抄至 https://www.cnblogs.com/miantest/p/7289694.html 一.在 macOS 下如何安装 (https://www.telerik.com/fid ...
- Effective Java理解笔记系列-第2条-何时考虑用构建器?
为什么写这系列博客? 在阅读<Effective Java>这本书时,我发现有许多地方需要仔细认真地慢慢阅读并且在必要时查阅相关资料才能彻底搞懂,相信有些读者在阅读此书时也有类似感受:同时 ...
- 【硬件】认识和选购多核CPU
2.1 认识和选购多核CPU CPU在电脑系统中就像人的大脑一样,是整个电脑系统的指挥中心,电脑的所有工作都由CPU进行控制和计算.它的主要功能是负责执行系统指令,包括数据存储.逻辑运算.传输控制.输 ...
- Oracle - ORA-19809: 超出了恢复文件数的限制
场景重现 使用rman执行以下命令进行数据库备份的时候出现异常: RMAN> backup database; 出现如下错误: # 主要异常信息如下: # ... RMAN-00571: === ...
- GitLab 服务器宕机时的项目代码恢复方法
重要前提:GitLab 数据挂载盘必须能够正常读取,且 /var/opt/gitlab/git-data/repositories 目录下的数据可以完整拷贝. 当 GitLab 服务器意外宕机且没有备 ...
- unigui的部署【9】
1.UniGUIServerModule的事件: procedure TUniServerModule.UniGUIServerModuleBeforeInit(Sender: TObject);be ...
- 2025年最流行的5个Python ASGI服务器及其核心特性与适用场景
以下是2025年最流行的5个Python ASGI服务器及其核心特性与适用场景: 1. Uvicorn • 核心优势: • 基于uvloop和httptools,性能远超传统WSGI服务器,支持HTT ...
- System V信号量 vs. POSIX信号量:核心区别与选型指南
System V信号量 vs. POSIX信号量:核心区别与选型指南 最近在学习linux系统编程的章节,接触到了两种信号量,所以专门研究了二者的区别,将二者的对比记录于此. 在Linux多线程/进程 ...