tarjan
对于普通图,尤其是无向图,其实除了拓扑排序没有什么得力的算法可以处理信息,而树上问题却有着众多美妙的算法,那么可以想办法把图转化成树
有两种方法:tarjan 与 \(dfs\) 树
强连通分量
有向图强连通分量判断:\(low[u]==dfn[u]\)
缩点:枚举每条有向边,判断是否不在一个连通块
P2746 [USACO5.3]校园网Network of Schools
对于第二问,注意在无环有向图上大多数情况下也是不能 \(dp\) 的,会算重
这道题就是要统计一下入度与出度,取个 \(max\) 即可
同样不能进行 \(dp\),用 \(bitset\) 记录能到达的是哪些点即可
发现覆盖的是一段区间,那么采用线段树优化建图,然后再跑 \(tarjan\)
类似于一个匈牙利的过程,如果相关的边形成了环那么就可以顺次进行了
这个环可以用 \(tarjan\) 来求强连通分量来解决
具体图这样画
题意为找到一种混合图定向方案是的强连通
结论是对于一条未定无向边,贪心考虑往那边走
即看起点集合当前能否走到终点,如果不能就指向终点
另一端类似
可以反证来证明这样做的正确性
AT3945 [ARC092D] Two Faced Edges
首先一定要形式化条件:
- \(v\) 可以到 \(u\)
- \(u\) 可以不经过当前边到 \(v\)
必须满足恰好一个
第一个直接 \(dfs\) 或者 \(tarjan\)
第二个可以用 \(bitset\) 等,考虑一个巧妙而简单的做法:
从 \(u\) \(dfs\),并记录每个点是由 \(u\) 的哪个出点遍历到的
把 \(u\) 出边反向,再记录一次,两次不同的就是可以到达的
点双
点双判断:\((u!=rt||flag>1)low[v]\ge dfn[u]\)
点双缩点:注意所有割点单独成点,并且属于多个连通块,然后一样的枚举边
边双
边双判断:\(low[v]>dfn[u]\)
边双缩点,进行一次 \(dfs\),不经过割边