【笔记】2-SAT (tarjan)

 2023-09-13 阅读 15 评论 0

摘要:TWO-SAT略解: Part 1 (引入): 其实2-SAT是用来解决一系列类似如果我怎么怎么样,他就怎么怎么怎么样的东西,具体来说就是只有两种状态,两种状态不能兼得。 举个例子: \(A\) 说如果 \(B\) 去参加群架,那我也得去

TWO-SAT略解:

Part 1 (引入):

其实2-SAT是用来解决一系列类似如果我怎么怎么样,他就怎么怎么怎么样的东西,具体来说就是只有两种状态,两种状态不能兼得。

举个例子:

\(A\) 说如果 \(B\) 去参加群架,那我也得去。

\(B\) 说如果有群架,那我跟 \(C\) 去一个就可以了。

\(C\) 说如果有群架,那我肯定去。

发现这道题其实咱小学就会做了只要画个表格,填个表格就行了。

那考虑怎么让计算机快速的求出这个东西。

Part 2 (口糊):

还是以上面那个例子。

对于 \(A\) 说的话,咱可以这样连边: \(B->A\)

对于 \(B\) 说的话,咱这么连 \(B'->C,C'->B\)

对于 \(C\) 说的话,咱这么连 \(C'->C\)

(所有的'表示这个点不选)

然后考虑怎么做这个玩意儿。

我们可以对它跑一边tarjan求出所有强连通分量,然后按照拓扑序判断每个点选还是不选。

为什么是拓扑序呢?

考虑\(x->x'\),那么肯定如果 \(x\) 选了 \(x'\) 也得选,但是按照咱的说法,这条边的意思是:\(x\) 这个点一定不选。那就矛盾了,只能选拓扑序大的

这里说一下关于tarjan的小技巧,tarjan出来给出的就是反拓扑序,所以其实我们要找的是强连通分量编号小的。

Part 3 (代码):

inline bool two_sat(){for(int i=1;i<=n;++i)if(scc[i]==scc[i+n]) return false;return true;
}

尴尬,好短啊。。。

Part 4 (例题):

JSOI原题:

发现这题其实是个垃圾题,每种材料只有两种做法,跑一遍裸的2-SAT

模板题:

这题可一用来练输出方案。

CF875C:

这题是真的好题,乍一眼看不会,其实是2-SAT,可以参考这篇博文:

CR我都帮你安利了还不帮我推销推销

大概就这样了,最后一题博主的题解:(还没写,到时候补上。。。)

转载于:https://www.cnblogs.com/JCNL666/p/10765514.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/53671.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息