关键路径(Java)

一、四个核心时间(必须背)

符号 全称 含义 对象
etv 事件最早发生时间 事件最早什么时候能发生 顶点
ltv 事件最晚发生时间 事件最晚什么时候必须发生 顶点
ete 活动最早开始时间 活动最早什么时候能开始
lte 活动最晚开始时间 活动最晚什么时候必须开始

二、计算公式

1. etv(正向,取最大)

复制代码
etv[v] = max(etv[u] + w)

一个事件必须等所有前置活动都完成才能发生 → 取最大值

2. ltv(反向,取最小)

复制代码
ltv[u] = min(ltv[v] - w)

一个事件不能拖累后续事件 → 取最小值

3. ete(活动最早开始)

复制代码
ete = etv[活动起点]

4. lte(活动最晚开始)

复制代码
lte = ltv[活动终点] - 活动耗时

三、判断关键活动

复制代码
ete == lte  →  该活动是关键活动

所有关键活动组成的路径就是 关键路径,决定了整个项目的最短工期。


四、计算步骤(四步法)

复制代码
1. 拓扑排序,得到拓扑序列
2. 正向遍历拓扑序,计算每个顶点的 etv
3. 反向遍历拓扑序,计算每个顶点的 ltv
4. 遍历每条边,计算 ete 和 lte,输出 ete == lte 的边

五、图解记忆

text 复制代码
      活动(边)
   u -----w----> v

   etv[u] 已知          etv[v] = max(etv[u] + w)
   ltv[u] = min(ltv[v] - w)   ltv[v] 已知

   ete = etv[u]
   lte = ltv[v] - w

六、代码骨架(Java)

java 复制代码
// 1. 正向:计算 etv
for (int u : topo) {
    for (Edge e : graph[u]) {
        etv[e.to] = Math.max(etv[e.to], etv[u] + e.w);
    }
}

// 2. 反向:计算 ltv
Arrays.fill(ltv, etv[n-1]);
for (int i = topo.size() - 1; i >= 0; i--) {
    int u = topo.get(i);
    for (Edge e : graph[u]) {
        ltv[u] = Math.min(ltv[u], ltv[e.to] - e.w);
    }
}

// 3. 输出关键活动
for (int u = 0; u < n; u++) {
    for (Edge e : graph[u]) {
        int ete = etv[u];
        int lte = ltv[e.to] - e.w;
        if (ete == lte) {
            System.out.println(u + " -> " + e.to);
        }
    }
}

七、一句话总结

etv 正向取最大,ltv 反向取最小
ete = etv[起点],lte = ltv[终点] - w
ete == lte 的活动,就是关键路径

八、课

相关推荐
C雨后彩虹1 小时前
SpringBoot整合Redis String,全套原生API讲解,覆盖80%缓存业务场景
java·数据结构·spring boot·redis·string
凤凰院凶涛QAQ1 小时前
《C++转Java快速入手系列》实践篇:图书系统
java·开发语言·c++
大大杰哥1 小时前
2025ccpc南昌补题笔记(前六题)
c++·笔记·算法
缪懿1 小时前
javaEE:网络编程基础
java·网络·java-ee
手写码匠1 小时前
手写 AI 智能路由系统:从零构建多模型调度与负载均衡
人工智能·深度学习·算法·aigc
sheeta19981 小时前
LeetCode 每日一题笔记 日期:2026.05.14 题目:2784. 检查数组是否是好的
笔记·算法·leetcode
故事还在继续吗1 小时前
DPDK 教程(三):多队列 + RSS + 多 worker 的最小转发 / Echo
算法·哈希算法·dpdk
Web极客码1 小时前
Python Deque:构建实时滑动窗口与高性能缓存的“隐藏高手”
java·python·缓存
AI科技星1 小时前
全域数学·体积与表面积通项定理【乖乖数学】
人工智能·算法·数学建模·数据挖掘·机器人