【数据结构】图-----关键路径

一、核心前提

  1. AOE 网 :有向无环、带权边,边代表活动,顶点代表事件;源点(起点:入度为 0)、汇点(终点:出度为 0)。
  2. 关键路径 :从源点 → 汇点最长路径 ;决定工程最短完成时间 ,路径上活动为关键活动

二、四大必背参数(考试核心)

设:顶点为事件,边为活动

  1. ve[i] :事件 i 的最早发生时间
  2. vl[i] :事件 i 的最晚发生时间
  3. e :活动最早开始时间
  4. l :活动最晚开始时间 l−e=0 → 该活动为关键活动

计算公式

  1. 最早发生时间(正向拓扑)源点权

  2. 最晚发生时间(逆拓扑)汇点汇点权

  3. 活动时间

  • 活动 <u,v>:e=ve[u],l=vl[v]−w

三、算法步骤

  1. 对 AOE 网做拓扑排序
  2. 按拓扑序正向遍历,求数组 ve
  3. 逆拓扑序反向遍历,求数组 vl
  4. 遍历所有边,计算 、
  5. l−e=0 的边 → 关键活动,串联即为关键路径

四、完整 C 语言代码(邻接表・带详细注释)

复制代码
#include <stdio.h>
#include <string.h>
#define MAXN 105
#define INF 0x3f3f3f3f

// 边结点:终点、权值、后继边
typedef struct Edge{
    int to,w;
    struct Edge *next;
}Edge;

Edge* G[MAXN];
int n,m;
int in[MAXN];        // 入度
int topo[MAXN],cnt;  // 拓扑序列
int ve[MAXN],vl[MAXN];

// 加边
void addEdge(int u,int v,int w){
    Edge *p=(Edge*)malloc(sizeof(Edge));
    p->to=v; p->w=w; p->next=G[u];
    G[u]=p;
    in[v]++;
}

// 1.拓扑排序,得到topo数组
void TopSort(){
    int stk[MAXN],top=0;
    cnt=0;
    for(int i=1;i<=n;i++)
        if(in[i]==0) stk[top++]=i;

    while(top>0){
        int u=stk[--top];
        topo[++cnt]=u;
        for(Edge *p=G[u];p;p=p->next){
            int v=p->to;
            in[v]--;
            if(in[v]==0) stk[top++]=v;
        }
    }
}

// 2.求ve:正向拓扑
void getVE(){
    memset(ve,0,sizeof(ve));
    for(int i=1;i<=cnt;i++){
        int u=topo[i];
        for(Edge *p=G[u];p;p=p->next){
            int v=p->to;
            if(ve[v] < ve[u]+p->w)
                ve[v] = ve[u]+p->w;
        }
    }
}

// 3.求vl:逆拓扑
void getVL(){
    for(int i=1;i<=n;i++) vl[i]=ve[topo[cnt]];
    for(int i=cnt;i>=1;i--){
        int u=topo[i];
        for(Edge *p=G[u];p;p=p->next){
            int v=p->to;
            if(vl[u] > vl[v]-p->w)
                vl[u] = vl[v]-p->w;
        }
    }
}

// 4.查找并输出关键活动、关键路径
void KeyPath(){
    printf("=====关键活动=====\n");
    for(int u=1;u<=n;u++){
        for(Edge *p=G[u];p;p=p->next){
            int v=p->to;
            int e = ve[u];
            int l = vl[v] - p->w;
            if(e == l){
                printf("关键活动:%d -> %d  权=%d\n",u,v,p->w);
            }
        }
    }
    printf("工程最短工期:%d\n",ve[topo[cnt]]);
}

int main(){
    scanf("%d%d",&n,&m);
    memset(G,0,sizeof(G));
    memset(in,0,sizeof(in));

    for(int i=1;i<=m;i++){
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        addEdge(u,v,w);
    }

    TopSort();
    getVE();
    getVL();
    KeyPath();
    return 0;
}

五、考点必背

  1. 关键路径仅存在于 AOE 有向无环图
  2. 关键路径 = 源点到汇点最长路径
  3. 关键活动:l−e=0
  4. 关键活动推迟→整体工期延长 ;非关键活动有时间余量,可适当延迟
  5. 拓扑求 ve,逆拓扑求 vl
  6. 关键路径可能多条
相关推荐
如君愿2 小时前
考研复习 Day 23 | 习题--计算机网络第一章、数据结构线性表
数据结构·计算机网络·考研·课后习题·记录考研
念何架构之路2 小时前
数组和切片实战
数据结构·算法·排序算法
重生之我是Java开发战士2 小时前
【数据结构】AVL树解析
数据结构·算法
Lazionr2 小时前
数据结构入门:栈实现全解析
c语言·数据结构
小π军2 小时前
STL之multiset 常见API介绍
数据结构·c++·算法
Shan12052 小时前
浅谈:从经典算法到实战优化的案例分析
数据结构
Resistance丶未来2 小时前
DeepSeek-V4 新手快速上手指南
数据结构·python·gpt·算法·机器学习·claude·claude 4.6
Lazionr3 小时前
数据结构队列详解:从概念到代码实现
c语言·数据结构
人道领域3 小时前
【LeetCode刷题日记】150.逆波兰表达式求值
java·数据结构·算法·leetcode