本篇文章主要是对tarjan不同用法的讲解 , 其主要目的是复习,当然初学也可以看鸭极有可能看不懂
目录 :1.有向图缩点
2.无向图割点
3.点双连通分量
1.有向图缩点
首先来一道经典题目
给定一个 n个点 m 条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。
允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。
洛谷3387 缩点
这个题的话很明显我们要用tarjan进行缩点,在图中寻找强连通分量对吧,因为这个点如果我们可以走过去的话,那么他所在的连通分量我们也可以都走一遍在回到这里。
当我们缩晚点之后,剩下的就一定是一个有向无环图(DAG)
证明的话可以用反证法 , 如果还有环的话就肯定还有连通 ,但这显然不可能
然后我们在这个图上进行一个dp + 拓扑就可以了(这两个不重要)
所以现在我们就来缩点!!! 先上代码!
#include<bits/stdc++.h>
using namespace std ;
const int M = 100000 + 5 ;
vector<int> g[M] ;
int bccnum[M] ;
int dfn[M] , low[M] ;
int zhi[M] , z[M] , vis[M] , sum[M] , ru[M];
int ans ;
int gx[6666][6666] , dis[6666];
stack<int> s ;
int cloc = 0 ;
int bccnt = 0 ;
inline void tarjan( int u , int fa)
{
dfn[u] = low[u] = ++cloc ;
s.push(u) ;
for( int i =