前言
一开始看到Tarjan我是拒绝的,觉得自己太菜了,肯定学不会,但是今天作业题要用到Tarjan,我只好硬着头皮学了,但是放心,这很简单
作用
Tarjan用来缩环上的点,这样图就会变成一个DAG,于是DP和最短路什么就可以乱搞了
过程
Tarjan是基于DFS序的一个算法,定义dfn为搜索时间戳,low为节点i即其子树中最小的dfn值。
那么也就是说,在一个环中,low值是一样的,而这个dfn值与low值相等的那个点就是搜索时的根,于是,这个点与栈顶到自身的所有点构成强联通分量。
例题:洛谷P3387
题目描述
给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。
允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。
输入格式:
第一行,n,m
第二行,n个整数,依次代表点权
第三至m+2行,每行两个整数u,v,表示u->v有一条有向边
输出格式:
共一行,最大的点权之和。
Sampleinput
1 | 2 2 |
Sampleout
1 | 2 |
对于这道题直接用Tarjan将所有强联通分量缩成一个点,因为走所有点显然更优(点权不为负)。
那么重构图就变成了一个DAG,我们直接记搜,求出子节点转移过来的最大贡献,向后dfs就行了。
代码
1 |
|