仙人掌&圆方树学习笔记
前言
一直觉得仙人掌和圆方树是非常高深的算法。
直到连续随机跳题跳到两道。我受不了啦!!!
于是点进了一个链接。(传销现场有木有啊!)
推荐链接 :戳这里
然后发现并没有想象中那么难。
而且,,,
很好玩。
日常赛前学算法(大雾
退役之前还是多多益善一波吧,错过了可能就遇不上了!
定义:仙人掌
任意一条边至多在一个环里的无向联通图
定义:仙人掌的圆方树
- 仙人掌 G = ( V , E ) G = (V, E) G=(V,E)的圆方树 T = ( V T , E T ) T = (V_T , E_T) T=(VT,ET)为满足以下条件的无向图:
V T = R T ∪ S T , R T = V , R T ∩ S T = ∅ V_ T = R_ T ∪ S_ T , R_ T = V, R_ T ∩ S_ T = ∅ VT=RT∪ST,RT=V,RT∩ST=∅,我们称 R T R_ T RT 集合为圆点、 S T S_ T ST集合为方点
∀ e ∈ E \forall e \in E ∀e∈E,若 e e e 不在任何简单环中,则 e ∈ E T e ∈ E_T e∈ET
对于每个仙人掌中的简单环 R R R,存在方点 p R ∈ S T p_ R ∈ S_ T pR∈ST ,并且 ∀ p ∈ R \forall p \in R ∀p∈R满足 ( p R , p ) ∈ E T (p _R , p) \in E_ T (pR,p)∈ET ,即对每个环建方点连所有点
严格的定义总是格外地难懂啊。
简单地说,把除了环上的所有边保留。对于每个环,新建一个方点,把所有环上的点与这个方点连边,删除原有的环上的边。
如何证明圆方树是一棵树?
首先显然,它仍然联通。
其次,对于每个环,新建的边数等于删除的边数,点数多了一个。
所以最后一定是一棵树。
圆方树的构造与性质
构造就是 T a r j a n Tarjan Tarjan缩环啊。
性质:
- 方点不会和方点连边。(不然就有一条边在两个环里了)
- 圆方数是一颗无根树,无论以仙人掌的哪个根构建出来的圆方树都是一样地,进一步地,仙人掌的圆方树和仙人掌是一一对应的。
- 定义以 r r r为根的仙人掌的 p p p子仙人掌为除去 p p p到 r r r的所有简单路径后, p p p所在联通块,则 p p p子仙人掌对应圆方树就是 r r r的圆方树上以 p p p为根的子树。
最后一条性质看上去很拗口。实际上,它想表达的意思是,仙人掌并不改变原图任意两点之间的连通性。这里的连通性包括路径信息,连边情况等。
简单圆方树问题
例1:bzoj4316: 小C的独立集
题目大意:给定一个仙人掌,求最大独立集。
这道题其实并不需要真正建立出圆方树。只需要在 T a r j a n Tarjan Tarjan的时候把环的情况处理一下。
具体地,对于树边,照常转移。直接跳过环。然后在环上合并子树的信息。唯一不同的是如果当前子仙人掌的根要选,那么环上和根相邻的两个节点都不能选(处理方法和基环树类似)。
#include<bits/stdc++.h>
const int M = 130000, N = 55000;
int