<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Tarjan |</title><link>https://sichen-wang.github.io/tags/tarjan/</link><atom:link href="https://sichen-wang.github.io/tags/tarjan/index.xml" rel="self" type="application/rss+xml"/><description>Tarjan</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Sat, 24 Jun 2023 11:00:56 +0000</lastBuildDate><image><url>https://sichen-wang.github.io/media/icon_hu_9dfcb674aa885f38.png</url><title>Tarjan</title><link>https://sichen-wang.github.io/tags/tarjan/</link></image><item><title>2-SAT 问题</title><link>https://sichen-wang.github.io/blog/2-sat-%E9%97%AE%E9%A2%98/</link><pubDate>Sat, 24 Jun 2023 11:00:56 +0000</pubDate><guid>https://sichen-wang.github.io/blog/2-sat-%E9%97%AE%E9%A2%98/</guid><description>&lt;h2 id="求解-2-sat-问题"&gt;求解 2-SAT 问题&lt;/h2&gt;
&lt;p&gt;\(2-\rm Sat\) 问题是求解某个 \(\rm bool\) 方程组，方程组中的每个方程被描述为：\(x_{i}\) 为真\(/\)假 或 \(x_{j}\) 为真\(/\)假。&lt;/p&gt;
&lt;p&gt;我们可以对每个 \(x_{i}\) 和 \(\lnot x_{i}\) 分别建点，\(x_{i}\) 为假看作 \(\lnot x_{i}\) 为真，这样方程就仅有一种类型了，即若 \(p\) 为真则 \(q\) 为真。具体来说，建一些边 \(u\to v\) 表示当 \(u\) 为真的时候 \(v\) 一定为真，比如有方程 \(p\) 为真或 \(q\) 为真时，建两条边 \(p\to \lnot q\) 和 \(q\to \lnot {p}\)。&lt;/p&gt;
&lt;p&gt;建完图后，显然同一个强连通分量中的点取值必然相同，那么如果 \(a\) 和 \(\lnot a\) 在同一个强连通分量里则该 \(\rm bool\) 方程组无解。易知，存在 \(a\) 和 \(\lnot a\) 在同一个强连通分量中为该 \(\rm bool\) 方程组无解的充要条件。&lt;/p&gt;
&lt;p&gt;对于其它的点，每对 \(a\) 和 \(\lnot a\) 中有且仅有一个为真，我们令拓扑序大的那个为真。可以分情况证明其最优性 ：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;若 \(a\) 和 \(\lnot a\) 在 \(\rm DAG\) 的同一条链上，那么拓扑序大的必然为真，否则两个都为真与题意相悖。&lt;/li&gt;
&lt;li&gt;若 \(a\) 和 \(\lnot a\) 在不同链上，那么两个点的取值其实无所谓，但一定要跟拓扑序相关。因为每条链上拓扑序的大小关系时严格的，用拓扑序规定某个点取值是否为真可以使为真的点在同一条链上，尽可能降低对其他点的影响。另外，为了保证跟上一种情况的统一性，仍选择令拓扑序大的点为真。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另一方面，我们发现 \(\rm Tarjan\) 缩点所求出的 \(\rm SCC\) 强连通分量数组的值负相关，可以理解为拓扑序更小的点更后入栈，也更先出栈编号。故最后对比 \(a\) 和 \(\lnot a\) 的 \(\rm SCC\) 值即可判断它们谁为真谁为假。&lt;/p&gt;
&lt;h2 id="经典例题"&gt;经典例题&lt;/h2&gt;
&lt;h3 id="lg6378-riddle"&gt;[LG6378] Riddle&lt;/h3&gt;
&lt;p&gt;对树上每个点建立一个 \(\rm bool\) 变量，取值为 \(1\) 表示这个点选。&lt;/p&gt;
&lt;p&gt;使用 \(\rm 2-Sat\) 的通用做法，建立为每个点的状态建立两个点 \(u\) 和 \(\lnot u\)，分别对每个限制考虑 ：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每条边至少有一个关键点，则对于一条边 \(u-v\) 若 \(\lnot u\) 则 \(v\)，若 \(\lnot v\) 则 \(u\)，故连接 \(\lnot u\to v\) 和 \(\lnot v\to u\)。&lt;/li&gt;
&lt;li&gt;每个部分最多有一个关键点，则如果 \(u\) 被选了，那么同一个块中所有点都不能选，连接 \(u\to \lnot v\)。 但是我们发现这样连边是 \(\Theta(n^{2})\) 的，所以前缀和优化连边即可。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;建好图以后直接跑 \(\rm 2-Sat\)，时间复杂度 \(\Theta(n)\)。&lt;/p&gt;
&lt;h3 id="poi2011-kon-conspiracy"&gt;[POI2011] KON-Conspiracy&lt;/h3&gt;
&lt;p&gt;首先转化题意，这道题要求的是将一张无向图划分成一个团和一个独立集的方案数。&lt;/p&gt;
&lt;p&gt;首先找出一种合法的方案是很容易的，是一个裸的 \(\rm 2-Sat\) 问题。&lt;/p&gt;
&lt;p&gt;考虑找出一种方案后统计方案数。首先有如下性质 ：&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;ul&gt;
&lt;li&gt;一个团中不可能取出一个以上的点加入独立集，因为两点之间必有连边。&lt;/li&gt;
&lt;li&gt;一个独立集中不可能取出一个以上的点加入团，因为两点之间必无连边。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以可以直接分别枚举团和独立集中的每个点，交换它们即可。&lt;/p&gt;
&lt;p&gt;时间复杂度 \(\rm \Theta(n^{2})\)。&lt;/p&gt;
&lt;h3 id="北京省选集训-2019-完美塔防"&gt;[北京省选集训 2019] 完美塔防&lt;/h3&gt;
&lt;p&gt;首先预处理哪些炮台会互相打到，若存在，则输出 &lt;code&gt;IMPOSSIBLE&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;然后发现有如下结论：&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;每个空地最多可以被两个炮台打到。
因为每个空地最多在纵横两个方向上被打到，若还存在一个，则必定会打到其中一个炮台。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;于是对每个炮台，它的纵横情况设为 \(0/1\)，每个空地会加入一个形如 \(a\ or\ b\) 的条件，这就变成了经典的 \(\rm 2-Sat\) 问题。&lt;/p&gt;
&lt;p&gt;时间复杂度 \(\Theta(Tn^{3})\)。&lt;/p&gt;
&lt;h3 id="hnoi2010-平面图判定"&gt;[HNOI2010] 平面图判定&lt;/h3&gt;
&lt;p&gt;首先有平面图中的欧拉定理，设一张无向连通图点数为 \(v\)，边数为 \(e\)，面数为 \(f\)，则有 ：&lt;/p&gt;
\[
v-e+f=2
\]&lt;p&gt;考虑通过对 \(e\) 进行归纳证明该式。&lt;/p&gt;
&lt;p&gt;当 \(e=0\) 时显然成立。&lt;/p&gt;
&lt;p&gt;若当 \(e'=e-1\) 时该式成立，我们要证 \(v-e+f=1\) 成立只需证添加一条边会使得面数恰好增加 \(1\)。 而对于这个问题，我们可以分类讨论，若这条边加在某个面的中间，那么其必将这个面分成两半，若这条边加在图形外面，那么会围出一块新的区域，也会使面数恰好增加 \(1\)。&lt;/p&gt;
&lt;p&gt;故该式成立。&lt;/p&gt;
&lt;p&gt;我们进一步探究平面图的性质。定义面的度数为与其相邻的面的数量，显然对于每条边都会有恰好两个面与其相邻，故所有面的度数之和为 \(2e\)。 又因为每个面至少三条边，所以度数不小于 \(3\)，进而有 \(3f\) 不大于所有面的度数之和，故有 \(3f\leqslant 2e\)，将其带入平面图中的欧拉定理可得 ：&lt;/p&gt;
\[
e\leqslant 3v-6
\]&lt;p&gt;于是不满足该式的无向连通图均不为平面图，进而可以将 \(m\) 限制到与 \(n\) 同数量级。&lt;/p&gt;
&lt;p&gt;我们发现题目给定了哈密顿回路，于是考虑以这个环作为中心考虑问题。&lt;/p&gt;
&lt;p&gt;我么发现对于任意一条边，它要么从环内连接，要么从环外连接，并且如果有两条边 \(u-v\) 和 \(u'-v'\)，且满足 \(u\lt u'\lt v\lt v'\)，那么它们不能连在同一面。于是可以通过这种关系构建 \(\rm 2-Sat\) 模型。&lt;/p&gt;
&lt;p&gt;时间复杂度 \(\Theta(Tn)\)。&lt;/p&gt;</description></item><item><title>缩点 &amp; 割点 &amp; 割边</title><link>https://sichen-wang.github.io/blog/%E7%BC%A9%E7%82%B9-%E5%89%B2%E7%82%B9-%E5%89%B2%E8%BE%B9/</link><pubDate>Sat, 24 Jun 2023 11:00:56 +0000</pubDate><guid>https://sichen-wang.github.io/blog/%E7%BC%A9%E7%82%B9-%E5%89%B2%E7%82%B9-%E5%89%B2%E8%BE%B9/</guid><description>&lt;h2 id="tarjan-算法"&gt;Tarjan 算法&lt;/h2&gt;
&lt;h3 id="强连通分量"&gt;强连通分量&lt;/h3&gt;
&lt;p&gt;若图 \(G\) 中存在一个子图 \(G'\)，\(G'\) 中任意两点均可互相到达，则称 \(G'\) 为 \(G\) 的一个&lt;strong&gt;强连通分量&lt;/strong&gt;。若 \(G'\) 不存在一个严格子图为强连通分量，则 \(G'\) 为 \(G\) 的&lt;strong&gt;极大&lt;/strong&gt;强连通分量。&lt;/p&gt;
&lt;p&gt;图的强连通分量可以考虑使用 \(\rm Tarjan\) 算法求解。&lt;/p&gt;
&lt;p&gt;\(\rm Tarjan\) 算法的思想是这样的，如果一个点的 \(\rm dfs\) 序等于他能访问到的最小的 \(\rm dfs\) 序，那么在 \(\rm dfs\) 树中，它的下方会出现一个强连通分量，且所有最小能访问到的 \(\rm dfs\) 序等于它的点，属于这个强连通分量。&lt;/p&gt;
&lt;p&gt;时间复杂度 \(\Theta(n+m)\)。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;参考代码：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Tarjan&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dfn&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;tix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Sta&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;dfn&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt; &lt;span class="n"&gt;Tarjan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;SCC&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;dfn&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dfn&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SCC&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Sta&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;SCC&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Sta&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="点边双连通分量"&gt;点/边双连通分量&lt;/h3&gt;
&lt;p&gt;如果在 \(\rm dfs\) 树上，某个结点 \(u\) 存在一个子节点 \(v\) ，满足 \(low_{v}\geqslant dfn_{u}\) ，则说明 \(v\) 想到达 \(u\) 的祖先结点必须经过 \(u\)，所以 \(u\) 是一个割点。&lt;/p&gt;
&lt;p&gt;当然，根节点不能通过这种方式来判断，应该看它的子节点数是否大于等于 \(2\)，如果是，则它为割点。&lt;/p&gt;
&lt;p&gt;遍历的时候要记得判掉父子边。&lt;/p&gt;
&lt;p&gt;和判断割点的方法几乎一模一样，唯一的区别是判断 \(dfn_{u}\lt low_{v}\) 而不是 \(dfn_{u}\leqslant low_{v}\)。（如果从 \(v\) 出发连 \(u\) 都无法到达，那么 \((u, v)\) 就是一条割边。&lt;/p&gt;
&lt;p&gt;判断割边的时候根节点不需要特殊考虑。&lt;/p&gt;
&lt;p&gt;时间复杂度 \(\Theta(n+m)\)。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;参考代码：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Tarjan&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;rt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dfn&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;tix&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;son&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;dfn&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;son&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Tarjan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;rt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;dfn&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;rt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;cut&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;dfn&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;rt&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;son&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;cut&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="经典例题"&gt;经典例题&lt;/h2&gt;
&lt;h3 id="国家集训队-稳定婚姻"&gt;[国家集训队] 稳定婚姻&lt;/h3&gt;
&lt;p&gt;首先在夫妻之间连有向边 \(B_{i}\to G_{i}\)，然后在情人之间连有向边 \(G_{i}\to B_{i}\)。&lt;/p&gt;
&lt;p&gt;可以发现，若 \(G_{i}\) 和 \(B_{i}\) 的婚姻情况发生了改变，那么一定存在一个从 \(G_{i}\) 开始 \(B_{i}\) 结束的环。&lt;/p&gt;
&lt;p&gt;于是我们使用 \(\rm Tarjan\) 算法求强连通分量，若 \(B_{i}\) 与 \(G_{i}\) 属于同一个强连通分量，那他们一定属于一个环，则他们是不安全的，否则就是安全的。&lt;/p&gt;
&lt;p&gt;时间复杂度 \(\Theta(n+m)\)。&lt;/p&gt;
&lt;h3 id="zjoi2007-最大半连通子图"&gt;[ZJOI2007] 最大半连通子图&lt;/h3&gt;
&lt;p&gt;首先缩点，发现强连通分量内的点一定属于同一个极大半连通子图。&lt;/p&gt;
&lt;p&gt;然后将 \(\rm DAG\) 画出来发现最大半连通子图一定是某条从无入度结点到无出度结点的链，长度和方案数直接 \(\rm DAG\) 上 \(\rm DP\) 即可。&lt;/p&gt;
&lt;p&gt;需要注意的是，在这题中，由于求的是导出子图，所以不能有重边。&lt;/p&gt;
&lt;p&gt;时间复杂度 \(\Theta(n+m)\)。&lt;/p&gt;
&lt;h3 id="hnoi2012-矿场搭建"&gt;[HNOI2012] 矿场搭建&lt;/h3&gt;
&lt;p&gt;先把个点和点双连通分量处理出来，对每个点双分开处理：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;若该点双无割点，则需要建两个出口。&lt;/li&gt;
&lt;li&gt;若该点双有一个割点，则需要在这个点双内建一个出口，且不能建在割点上。&lt;/li&gt;
&lt;li&gt;若该点有两个以上割点，则不需要建出口，因为一定可以从某个割点跑出去。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;方案数直接乘法原理计算即可。&lt;/p&gt;
&lt;p&gt;时间复杂度 \(\Theta(n+m)\)。&lt;/p&gt;
&lt;h3 id="haoi2010-软件安装"&gt;[HAOI2010] 软件安装&lt;/h3&gt;
&lt;p&gt;可以发现这是一棵基环外向树，依题意环中结点必须选，剩下的构成一棵树，直接树上背包即可。&lt;/p&gt;
&lt;p&gt;时间复杂度 \(\Theta(nm)\)。&lt;/p&gt;</description></item></channel></rss>