作者以此文向作者详细的讲解有向图的最长链问题。
假设有这么一个图。
要求图中的最长链。(长度为经过的点数,重复只算一次,点、边可以重合)
经过观察,我们发现最长链是这条链。
接下来我们发现,同一个强连通分量中的点最好都选上,如下图。
走 4 -> 8 -> 9 -> 4 这个环一定比不走更优,因为这是个强连通分量,强连通分量内部可以互相到达,就是说进入和出去的点可以任意选,且把所有点都走了并不会影响接下来的行动。因此我们直接把每个强连通分量缩点,如果进入强连通分量中的一个点,就把整个强连通分量都走完。
我们看所点后的图。
我们把每个强连通分量存一个它里面的点数,如下图。
接下来原图变成了一个拓扑图,直接在上面跑拓扑排序最长链即可。
具体来说,每个缩玩点后的点记录一个 f u f_u fu,表示终点是这个点的最长链,初始化 f u = 1 f_u = 1 fu=1,转移 f j = f u + 1 ( ( u , j ) ∈ E ) \displaystyle f_j = f_u + 1((u, j) \in E) fj=fu+1((u,j)∈E),其中 E E E 为边集。
其实不需要真的拓扑排序,基于 T a r j a n Tarjan Tarjan 算法 d f s dfs dfs 的特性,强连通分量本身就满足拓扑序的逆序。所以直接从 1 开始依次遍历转移即可。
于是这个问题得以解决。