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

一、核心前提

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

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

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

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

计算公式

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

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

  3. 活动时间

  • 活动 <u,v>:e=veu,l=vlv−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. 关键路径可能多条
相关推荐
CSharp精选营16 小时前
关系型 vs 非关系型:从原理到选型,一文搞定数据库核心分类
数据结构·nosql·关系型数据库·非关系型数据库·技术选型
刘马想放假4 天前
Modbus 全栈技术解析:TCP、RTU、ASCII、RTU over TCP
数据结构·网络协议
北域码匠5 天前
冒泡排序太慢?鸡尾酒排序双向优化,原生 C# 零第三方库完整代码
数据结构·排序算法·泛型·c# 算法·鸡尾酒排序·原生 c# 开发·冒泡排序优化·嵌入式算法
Darling噜啦啦12 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
小小工匠13 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
玖玥拾13 天前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
Qres82113 天前
算法复键——树状数组
数据结构·算法
牛油果子哥q13 天前
并查集(DSU)超精讲,路径压缩、按秩合并、万能模板、连通性判定、最小生成树与刷题实战全解
数据结构·c++·最小生成树·并查集
凌波粒13 天前
LeetCode--491.递增子序列(回溯算法)
数据结构·算法·leetcode
WL学习笔记13 天前
单项不带头不循环链表
数据结构·链表