📌  相关文章
📜  图中以顶点 V 结束的最长路径的长度(1)

📅  最后修改于: 2023-12-03 14:50:48.804000             🧑  作者: Mango

图中以顶点 V 结束的最长路径的长度

在图算法中,常常需要计算从一个起始点到一个终止点的最短路径或最长路径,以确定最优的路径方案。本文将介绍如何计算图中以顶点 V 结束的最长路径的长度。

定义

在有向无环图(DAG)中,一个路径的权重是路径上所有边的权重之和。给定一个 DAG 和一个顶点 V,我们的目的是找到从图上的任意点到 V 的最长路径的长度。

解法

我们可以使用拓扑排序,一步步更新图的顶点的最长路径,直到到达顶点 V 为止。具体步骤如下:

  1. 对 DAG 进行拓扑排序,得到拓扑序列 L。
  2. 初始化所有的顶点到 V 的最长路径为0,但是 V 到 V 的最长路径为1。
  3. 对于每个 L 中的顶点 u,遍历从 u 出发的所有边 (u,v)。如果从 u 到 v 的路径长度加上 u 到 V 的最长路径长度大于 v 终点的最长路径,则更新 v 终点的最长路径为从 u 到 v 的路径长度加上 u 到 V 的最长路径长度。

伪代码如下:

topological_sort(G) // 用拓扑排序得到 L

for each vertex u in L:
    if u == V:
        distance[u] = 1 // V 到 V 的最长路径长度为 1
    else:
        distance[u] = 0 // 其他顶点到 V 的最长路径长度先初始化为 0

    for each vertex v adjacent to u:
        if distance[u] + weight(u, v) > distance[v]:
            distance[v] = distance[u] + weight(u, v)

最终,我们得到的 distance[V] 就是从任意点到 V 的最长路径的长度。

性能分析

  • 时间复杂度:O(V+E),其中 V 是顶点数,E 是边数。拓扑排序耗费 O(V+E) 的时间,但是我们仅仅遍历了每个顶点和其出边一次,所以总的运行时间为 O(V+E)。

示例

例如,在下面的 DAG 中,要计算任意顶点到顶点 E 的最长路径长度。

    A--->B--->D
   / \       /
  /   \     /
 V     C   /
  \       /
   \     /
    -->E-->

首先进行拓扑排序:[V, A, C, B, D, E]

初始化 distance 数组,对于任意 u,distance[u] 表示 u 到 E 的最长路径长度,因为我们要求任意点到 E 的最长路径。

distance = {
    V: 0,
    A: 0,
    C: 0,
    B: 0,
    D: 0,
    E: 0
}

从 V 开始更新 distance 数组。V 是 E 的直接前驱,所以我们先更新 E 的最长路径。

  • 从 V 到 E 的路径长度为 1,加上 V 到 V 的路径长度 1,得到 distance[E] = 2。更新后的 distance 数组为:
distance = {
    V: 0,
    A: 0,
    C: 0,
    B: 0,
    D: 0,
    E: 2
}

然后是 D:

  • D 没有后继,因此我们跳过它。

然后是 B:

  • 从 B 到 E 的路径长度为 1,加上 B 到 V 的最长路径长度 0,得到 distance[E] = 2。更新后的 distance 数组为:
distance = {
    V: 0,
    A: 0,
    C: 0,
    B: 0,
    D: 0,
    E: 2
}

再遍历 C:

  • 从 C 到 E 的路径长度为 1,加上 C 到 V 的最长路径长度 0,得到 distance[E] = 2。更新后的 distance 数组为:
distance = {
    V: 0,
    A: 0,
    C: 0,
    B: 0,
    D: 0,
    E: 2
}

最后是 A:

  • 从 A 到 B 的路径长度为 1,加上 B 到 V 的最长路径长度 0,得到 distance[B] = 1。
  • 从 A 到 C 的路径长度为 1,加上 C 到 V 的最长路径长度 0,得到 distance[C] = 1。
  • 从 A 到 V 的路径长度为 1,加上 V 到 V 的路径长度 1,得到 distance[V] = 2。
  • 最后,从 A 到 E 的路径长度为 2,加上 A 到 V 的最长路径长度 2,得到 distance[E] = 4。更新后的 distance 数组为:
distance = {
    V: 2,
    A: 0,
    C: 1,
    B: 1,
    D: 0,
    E: 4
}

最终,我们得到了任意顶点到顶点 E 的最长路径长度为 4。

参考资料

  • 算法基础课第 2 部分 第 3 章
  • 张铭《算法学习笔记》
Markdown 返回结果
## 图中以顶点 V 结束的最长路径的长度

在图算法中,常常需要计算从一个起始点到一个终止点的最短路径或最长路径,以确定最优的路径方案。本文将介绍如何计算图中以顶点 V 结束的最长路径的长度。

### 定义

在有向无环图(DAG)中,一个路径的权重是路径上所有边的权重之和。给定一个 DAG 和一个顶点 V,我们的目的是找到从图上的任意点到 V 的最长路径的长度。

### 解法

我们可以使用拓扑排序,一步步更新图的顶点的最长路径,直到到达顶点 V 为止。具体步骤如下:

1. 对 DAG 进行拓扑排序,得到拓扑序列 L。
2. 初始化所有的顶点到 V 的最长路径为0,但是 V 到 V 的最长路径为1。
3. 对于每个 L 中的顶点 u,遍历从 u 出发的所有边 (u,v)。如果从 u 到 v 的路径长度加上 u 到 V 的最长路径长度大于 v 终点的最长路径,则更新 v 终点的最长路径为从 u 到 v 的路径长度加上 u 到 V 的最长路径长度。

```Python
topological_sort(G) # 用拓扑排序得到 L

for each vertex u in L:
    if u == V:
        distance[u] = 1 # V 到 V 的最长路径长度为 1
    else:
        distance[u] = 0 # 其他顶点到 V 的最长路径长度先初始化为 0

    for each vertex v adjacent to u:
        if distance[u] + weight(u, v) > distance[v]:
            distance[v] = distance[u] + weight(u, v)

最终,我们得到的 distance[V] 就是从任意点到 V 的最长路径的长度。

性能分析
  • 时间复杂度:O(V+E),其中 V 是顶点数,E 是边数。拓扑排序耗费 O(V+E) 的时间,但是我们仅仅遍历了每个顶点和其出边一次,所以总的运行时间为 O(V+E)。
示例

例如,在下面的 DAG 中,要计算任意顶点到顶点 E 的最长路径长度。

    A--->B--->D
   / \       /
  /   \     /
 V     C   /
  \       /
   \     /
    -->E-->

首先进行拓扑排序:[V, A, C, B, D, E]

初始化 distance 数组,对于任意 u,distance[u] 表示 u 到 E 的最长路径长度,因为我们要求任意点到 E 的最长路径。

distance = {
    V: 0,
    A: 0,
    C: 0,
    B: 0,
    D: 0,
    E: 0
}

从 V 开始更新 distance 数组。V 是 E 的直接前驱,所以我们先更新 E 的最长路径。

  • 从 V 到 E 的路径长度为 1,加上 V 到 V 的路径长度 1,得到 distance[E] = 2。更新后的 distance 数组为:
distance = {
    V: 0,
    A: 0,
    C: 0,
    B: 0,
    D: 0,
    E: 2
}

然后是 D:

  • D 没有后继,因此我们跳过它。

然后是 B:

  • 从 B 到 E 的路径长度为 1,加上 B 到 V 的最长路径长度 0,得到 distance[E] = 2。更新后的 distance 数组为:
distance = {
    V: 0,
    A: 0,
    C: 0,
    B: 0,
    D: 0,
    E: 2
}

再遍历 C:

  • 从 C 到 E 的路径长度为 1,加上 C 到 V 的最长路径长度 0,得到 distance[E] = 2。更新后的 distance 数组为:
distance = {
    V: 0,
    A: 0,
    C: 0,
    B: 0,
    D: 0,
    E: 2
}

最后是 A:

  • 从 A 到 B 的路径长度为 1,加上 B 到 V 的最长路径长度 0,得到 distance[B] = 1。
  • 从 A 到 C 的路径长度为 1,加上 C 到 V 的最长路径长度 0,得到 distance[C] = 1。
  • 从 A 到 V 的路径长度为 1,加上 V 到 V 的路径长度 1,得到 distance[V] = 2。
  • 最后,从 A 到 E 的路径长度为 2,加上 A 到 V 的最长路径长度 2,得到 distance[E] = 4。更新后的 distance 数组为:
distance = {
    V: 2,
    A: 0,
    C: 1,
    B: 1,
    D: 0,
    E: 4
}

最终,我们得到了任意顶点到顶点 E 的最长路径长度为 4。