Tarjan/2-SAT学习笔记
Tarjan/2-SAT
Tags:图论
作业部落
评论地址
Tarjan
用来求割边或者割点,求点双联通分量或者边双联通分量
点双联通分量:两个点之间有两条点不相交的路径
边双联通分量:两个点之间有两条边不相交的路径
Tarjan求LCA还不会
2-SAT
每种物品有选或者不选两种状态,有些限制条件形如
选了\(A\)则必须选\(B\),\(A\)和\(B\)不能同时选,必须选\(A\)等等
把逻辑限制关系变成连边
a->b表示如果\(a\)成立那么\(b\)一定成立
这个要求你理解逆否命题
逆否命题,举个例子,选\(A\)必须选\(B\),那么我选了\(B'\)就不能选\(A\),选\(B'\)就必须选\(A'\)
由于逆否命题产生的对称性使得\(2-SAT\)问题得以在\(O(n)\)时间求解
具体来说要求同时连接x->y y'->x'
这样跑一遍\(Tarjan\)缩点后如果统一物品的两种状态在同一个边双连通分量中就无解
否则可以输出方案,具体来说是每个点选择\(Tarjan\)缩成的超级点中编号最小的那个(也就是反图拓扑序最小的那个)
题单
Tarjan
- [x] [luogu3387]【模板】缩点 https://www.luogu.org/problemnew/show/P3387
- [x] [luogu3388]【模板】割点(割顶)https://www.luogu.org/problemnew/show/P3388
- [x] [APIO2009]抢掠计划 https://www.luogu.org/problemnew/show/P3627
- [x] [HAOI2006]受欢迎的牛 https://www.luogu.org/problemnew/show/P2341
- [ ] [USACO5.3]校园网 https://www.luogu.org/problemnew/show/P2746
- [ ] [luogu3398]仓鼠找sugar https://www.luogu.org/problemnew/show/P3398
- [x] [HNOI2006]潘多拉的宝盒 https://www.luogu.org/problemnew/show/P2321
- [ ] [HAOI2010]软件安装 https://www.luogu.org/problemnew/show/P2515
- [x] [HNOI2012]矿场搭建 https://www.luogu.org/problemnew/show/P3225
- [ ] [SDOI2010]所驼门王的宝藏 https://www.luogu.org/problemnew/show/P2403
2-SAT
- [x] [POI2001]和平委员会 http://cogs.pro:8080/cogs/problem/problem.php?pid=313
- [x] [JSOI2010]满汉全席 https://www.luogu.org/problemnew/show/P4171
- [x] [UOJ210]寻找罪犯 http://uoj.ac/problem/210
- [x] [NOI2017]游戏 https://www.luogu.org/problemnew/show/P3825
- [ ] [HNOI2010]平面图判定 https://www.luogu.org/problemnew/show/P3209
- [ ] [POI2010]KOL-Railway https://www.luogu.org/problemnew/show/P3497
Code
边双
void Tarjan(int x)
{
vis[x]=1;sta[++top]=x;
dfn[x]=low[x]=++tot;
for(int i=A.head[x],R=A.a[i].to;i;i=A.a[i].next,R=A.a[i].to)
if(!dfn[R]) Tarjan(R),low[x]=min(low[x],low[R]);
else if(vis[R]) low[x]=min(low[x],low[R]);
if(low[x]!=dfn[x]) return;
for(int k=sta[top],lst=0;lst!=x;lst=k,k=sta[--top])
vis[k]=0,bel[k]=x,val[x]+=val[k]*(k!=x);
}
点双
void Tarjan(int x,int f)
{
int s=0;dfn[x]=low[x]=++tot;
for(int i=head[x];i;i=a[i].next)
{
int R=a[i].to;if(R==f) continue;
if(dfn[R]) {low[x]=min(low[x],dfn[R]);continue;}
s++;Tarjan(R,x);tag[x]|=low[R]>=dfn[x];
low[x]=min(low[x],low[R]);
}
if(!f&&s==1) tag[x]=0;
}
!注意点双第7行一定要是dfn[R]
2-sat(和平委员会)
#include<cstdio>
#include<cstdlib>
#include<queue>
using namespace std;
const int N=41000;
struct edge {int next,fr,to;};
struct Map
{
edge a[N]; int head[N],cnt;
void link(int x,int y) {a[++cnt]=(edge){head[x],x,y};head[x]=cnt;}
}A,B;
int dfn[N],top,sta[N],vis[N],low[N];
int bel[N],tot,n,m,p[N],node;
queue<int> Q;
void Min(int &a,int b) {if(b<a) a=b;}
void Tarjan(int x)
{
vis[x]=1;sta[++top]=x; dfn[x]=low[x]=++tot;
for(int i=A.head[x],R=A.a[i].to;i;i=A.a[i].next,R=A.a[i].to)
if(!dfn[R]) Tarjan(R),Min(low[x],low[R]);
else if(vis[R]) Min(low[x],low[R]);
if(low[x]!=dfn[x]) return;++node;
for(int k=sta[top],lst=0;lst!=x;lst=k,k=sta[--top])
vis[k]=0,bel[k]=node;
}
int main()
{
// freopen("spo.in","r",stdin);
// freopen("spo.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n*2;i++) p[i]=i&1?i+1:i-1;
for(int i=1;i<=m;i++)
{
int x,y;scanf("%d%d",&x,&y);
A.link(x,p[y]);A.link(y,p[x]);
}
for(int i=1;i<=n*2;i++) if(!dfn[i]) Tarjan(i);
for(int i=1;i<=n*2;i+=2) if(bel[i]==bel[p[i]]) {puts("NIE");exit(0);}
for(int i=1;i<=n*2;i+=2) printf("%d\n",bel[i]<bel[p[i]]?i:p[i]);
}
Tarjan/2-SAT学习笔记的更多相关文章
- $tarjan$简要学习笔记
$QwQ$因为$gql$的$tarjan$一直很差所以一直想着要写个学习笔记,,,咕了$inf$天之后终于还是写了嘻嘻. 首先说下几个重要数组的基本定义. $dfn$太简单了不说$QwQ$ 但是因为有 ...
- <老友记>学习笔记
这是六个人的故事,从不服输而又有强烈控制欲的monica,未经世事的千金大小姐rachel,正直又专情的ross,幽默风趣的chandle,古怪迷人的phoebe,花心天真的joey——六个好友之间的 ...
- OGG学习笔记02-单向复制配置实例
OGG学习笔记02-单向复制配置实例 实验环境: 源端:192.168.1.30,Oracle 10.2.0.5 单实例 目标端:192.168.1.31,Oracle 10.2.0.5 单实例 1. ...
- python数据分析入门学习笔记
学习利用python进行数据分析的笔记&下星期二内部交流会要讲的内容,一并分享给大家.博主粗心大意,有什么不对的地方欢迎指正~还有许多尚待完善的地方,待我一边学习一边完善~ 前言:各种和数据分 ...
- 仙人掌&圆方树学习笔记
仙人掌&圆方树学习笔记 1.仙人掌 圆方树用来干啥? --处理仙人掌的问题. 仙人掌是啥? (图片来自于\(BZOJ1023\)) --也就是任意一条边只会出现在一个环里面. 当然,如果你的图 ...
- 【MarkMark学习笔记学习笔记】javascript/js 学习笔记
1.0, 概述.JavaScript是ECMAScript的实现之一 2.0,在HTML中使用JavaScript. 2.1 3.0,基本概念 3.1,ECMAScript中的一切(变量,函数名,操作 ...
- Linux 学习笔记之超详细基础linux命令 Part 13
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 12---------------- ...
- Linux 学习笔记之超详细基础linux命令 Part 8
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 7----------------- ...
- Deep learning with Python 学习笔记(5)
本节讲深度学习用于文本和序列 用于处理序列的两种基本的深度学习算法分别是循环神经网络(recurrent neural network)和一维卷积神经网络(1D convnet) 与其他所有神经网络一 ...
- 【Redis】命令学习笔记——字符串(String)(23个超全字典版)
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). 本篇基于redis 4.0.11版本,学习字符串( ...
随机推荐
- 最大公约数(GCD)与最小公倍数(LCM)的计算
给出两个数a.b,求最大公约数(GCD)与最小公倍数(LCM) 一.最大公约数(GCD) 最大公约数的递归: * 1.若a可以整除b,则最大公约数是b * 2.如果1不成立,最大公约数便是b ...
- 前端技术-HTML页面的加载
HTML页面的加载 HTML页面的加载实际上是基于http过程+浏览器对数据的解析渲染. http协议的请求过程是基于TCP协议的.http是要基于TCP连接基础上,简单的说,TCP单纯建立连接,不涉 ...
- 如何动态调用 C 函数
JSPatch 支持了动态调用 C 函数,无需在编译前桥接每个要调用的 C 函数,只需要在 JS 里调用前声明下这个函数,就可以直接调用: require('JPEngine').addExtensi ...
- shell批量远程连接mysql的方法
一.配置mysql服务器ip列表如下,可自定义: S1 1.1.1.1 3306 user passwd11 dbname_s1S2 2.2.2.2 3306 u ...
- Raft一致性算法
所有的分布式系统,都面临的一个问题是多个节点之间的数据共享问题,这个和团队协作的道理是一样的,成员可以分头干活,但总是需要共享一些必须的信息,比如谁是 leader, 都有哪些成员,依赖任务之间的顺序 ...
- HDU 5550 - Game Rooms(DP + 前缀和预处理)
链接: http://acm.hdu.edu.cn/showproblem.php?pid=5550 题意: 一个大楼有n(2≤n≤4000)层,每层可以建一个乒乓球房或者一个游泳房,且每种房间在大楼 ...
- BZOJ4259:残缺的字符串(FFT)
Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同 ...
- Linux无法识别Broadcom 802.11abgn无线网卡
折腾了好久,都无法解决 索性后来直接使用的usb外置网卡,勉强能用(使用极其不便) 最后使尽浑身解数,冲着萤火般的希望,好在没有放弃 正解就是下面这 完成重启即可 sudo cp /sys/fir ...
- 20155314 2016-2017-2 《Java程序设计》实验二 Java面向对象程序设计
20155314 2016-2017-2 <Java程序设计>实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UM ...
- 常用的sql语法_Row_Number
可用来分页,也可以用来egg:获取同类型的最新的信息 ROW_NUMBER() 说明:返回结果集分区内行的序列号,每个分区的第一行从1开始.语法:ROW_NUMBER () OVER ([ < ...