TaRJaN
零、前言
WCR 刷到了 tarjan 裸题。
我:“这不是一遍dfs一遍最短路完事了?”
WCR:“……(调试中)”
然后就想起来我也不会写 tarjan。。。
然后这是一篇复习 blog 。。。
一、基础
先上某度某科定义:
若一个无向图中的去掉任意一个节点(一条边)都不会改变此图的连通性,即不存在割点(桥),则称作点(边)双连通图。一个无向图中的每一个极大点(边)双连通子图称作此无向图的点(边)双连通分量。
然后就是缩点,缩点之后有向图会成为一个 \(DAG\) ,可以进行 拓扑\(DP\)
无向图缩点后就是一棵树。
1、缩点(强连通)
比如洛谷模板。
竟然做了一个小时。。。
坑点:不保证单源,从每个点开始 tarjan 。
特点:遍历完所有儿子后再判断是否在强连通内。
2、割边
交了2147483647次。。。
坑点:
- 如果非树边,要用dfn更新low。
- 判断是否割边,是
low[v]>dfn[u] - tot=1,因为要记录来边(不是来点)
3、割点
无需进行栈操作。判断是否是割点:low[v]>=dfn[u]
特判每个连通块的根:如果根连着两个或以上个连通块,则根也是割点。
二、进阶&&应用
可能主要是 (全都是?) 园方树 罢。
而且可能全都是兔队的罢。
首先是写法。
1、因为要建两张图,尽量一个用邻接表一个用vector,可能看着方便一点。
2、与之前不同,弹栈时不能弹当前节点u,因为u可能还在另一个点双中。
3、方点标号从n+1开始,区分圆方点。
铁人两项
简单路径:同一个点双内,所有的点 \(c\) ,满足从 \(u\) 到 \(v\) 至少存在一条简单路径经过点 \(c\) 。
点权:方点赋值为点双大小,圆点赋值为 \(-1\) 。
转化:起点终点固定时,中间点方案数 \(->\) 树上两点之间点权和。
改变求和方式:对于每个点,权值乘以经过该点的路径条数。
战略游戏
建出圆方树,割点数即为树上联通子图中圆点数减去 \(|S|\) 。
关于联通子图:正规求法是虚树之类的东东。。。我有个线段树区间覆盖的求法,正确性与可行性均不明。。。留坑等我颓废而不想颓废的时候填。。。
upd on 10/19:将所有点按DFS序排序,然后答案为 \(\frac{1}{2}×(\sum dis_{i,i+1} +dis_{n,1})\) 。
tourists
建出圆方树,问题变为求两点间点权最小值。(方点点权为周围圆点的最小值)
可是修改操作就很烦,一个圆点周围可能会有一堆方点。。。
于是修改定义:方点点权为儿子圆点的最小值,当路径LCA是方点时额外查询 fa[lca] 的值 。
然后方点可以开个multiset记录每个儿子的值。。。(逐渐离谱且毒瘤)
压力
两点之间的割点数,就是路径上圆点数。
可以很容易 树剖 树上差分 求出。
一眼树剖的绕着机房爬三圈!!!

浙公网安备 33010602011771号