The Realization of Solving the Length of Critical Path in AOE Network

question

In a directed acyclic graph, find the critical path and its length.

train of thought

1. Calculate the earliest occurrence time and latest occurrence time of each vertex (event) according to topological sorting and reverse topological sorting.
2. Use the above results to calculate the earliest start time and latest start time of each side (activity).
3. The activity of e[i->j] = l[i->j] is the key activity.

the code

#include <bits/stdc++.h>
using namespace std;
int n,m;
const int maxn = 1010;
struct node{
    
    
    int v;
    int w;
};
vector<node> G[maxn];
int inDegree[maxn],ve[maxn],vl[maxn];
//拓扑序列
stack<int> topOrder;
//拓扑序列,顺便求 ve 数组
bool topologicalSort(){
    
    
    queue<int> q;
    for (int i = 0; i < n; ++i) {
    
    
        if (inDegree[i] == 0){
    
    
            q.push(i);
        }
    }
    while (!q.empty()){
    
    
        int u = q.front();
        q.pop();
        topOrder.push(u);
        for (int i = 0; i < G[u].size(); ++i) {
    
    
            int v = G[u][v].v;
            inDegree[v]--;
            if(inDegree[v] == 0){
    
    
                q.push(v);
            }
            if(ve[u] + G[u][i].w > ve[v]){
    
    
                ve[v] = ve[u] + G[u][i].w;
            }
        }
    }
    if(topOrder.size() == n) return true;
    else return false;
}

//关键路径,不是有向无环图返回-1,否则返回关键路径长度
int CriticalPath(){
    
    
    memset(ve,0,sizeof(ve));
    if(topologicalSort() == false){
    
    
        return -1;
    }
    fill(vl,vl + n,ve[n-1]); //vl数组初始化,初始值为汇点的 ve 值
    //直接使用 topOrder 的出栈即为逆拓扑序列,求解 vl 数组
    while(!topOrder.empty()){
    
    
        int u = topOrder.top();
        topOrder.pop();
        for (int i = 0; i < G[u].size(); ++i) {
    
    
            int v = G[u][i].v;
            if(vl[v] - G[u][i].w < vl[u]){
    
    
                vl[u] = vl[v] - G[u][i].w;
            }
        }
    }
    //遍历邻接表的所有边,计算活动的最早开始时间和最晚开始时间
    for (int u = 0; u < n; ++u) {
    
    
        for (int i = 0; i < G[u].size(); ++i) {
    
    
            int v = G[u][i].v, w = G[u][i].w;
            int e = ve[u], l = vl[v] - w;
            if (e == l){
    
    
                printf("%d->%d\n",u,v);
            }
        }
    }
    return ve[n-1]; //返回关键路径长度
}

int main() {
    
    
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

Summarize

Find points first, then edge.

Guess you like

Origin blog.csdn.net/qq_19272233/article/details/119964556