• AOE网络,最长路关键路径的学习


    我只想说,被坑了

    总以为这本书上没有错。。。却出现了两个错误

    书上用的指针邻接表,我想学下数组模拟,然后就全改了

    一个点表示一个事件,一条边表示该活动的时间

    那么对于每个事件和每个活动都有最早可能开始时间和最迟允许开始时间了

    具体思路也不想写了,本想画个图来写篇博客。。浪费时间啊。。时间宝贵啊。。

    贴代码吧。。

    #include<cstdio>
    #include<cstring>
    
    const int maxn = 10000;//顶点个数最大值
    const int maxm = 10000;//边数最大值
    struct node{
        int to, w, id;//边的另一个顶点,持续时间,活动序号
        int next;
    }list1[maxn], list2[maxn];
    int p1[maxm], p2[maxm];//入边表,出边表
    int ind1[maxn], ind2[maxn];//入度, 出度
    int Ee[maxn];//各事件的最早可能开始时间
    int El[maxn];//各事件的最迟允许开始时间
    int e[maxm];//各活动的最早可能开始时间
    int l[maxm];//各活动的最迟允许开始时间
    int n, m;
    void criticalpath(){
        int top1 = -1;
        memset(Ee, 0, sizeof Ee);
        for(int i = 0; i < n; i ++){
            if(ind1[i] == 0){
                ind1[i] = top1;
                top1 = i;
            }
        }
        for(int i = 0; i < n; i ++){
            if(top1 == -1){
                printf("network has a cycle!\n");
                return;
            }
            int j = top1;
            top1= ind1[top1];
            for(int k = p1[j]; k != -1; k = list1[k].next){
                int v = list1[k].to;
                if( -- ind1[v] == 0){
                    ind1[v] = top1;
                    top1 = v;
                }
                if(Ee[j] + list1[k].w > Ee[v])
                  Ee[v] = Ee[j] + list1[k].w;
            }
        }
        int top2 = -1;
        for(int i = 0; i < n; i ++){
            El[i] = Ee[n-1];
            if(ind2[i] == 0){
                ind2[i] = top2;
                top2 = i;
            }
        }
        for(int i = 0; i < n; i ++){
            int j = top2;
            top2 = ind2[top2];
            for(int k = p2[j]; k != -1; k = list2[k].next){
                int v = list2[k].to;
                if( -- ind2[v] == 0){
                    ind2[v] = top2;
                    top2 = v;
                }
                if( El[j] - list2[k].w < El[v])
                  El[v] = El[j] - list2[k].w;
            }
        }
        memset(e, 0, sizeof e);
        memset(l, 0, sizeof l);
        for(int i = 0; i < n;i ++){
            for(int k = p1[i]; k != -1; k = list1[k].next){
                //puts("Asdf");
                int v = list1[k].to;
                int id = list1[k].id;
                e[id] = Ee[i];
                l[id] = El[v] - list1[k].w;
                //printf("%d %d\n", e[id], l[id]);
                if(e[id] == l[id])
                  printf("a%d : %d->%d\n", id, i, v);
            }
        }
    }
    void init(){
        memset(list1, 0, sizeof list1);
        memset(list2, 0, sizeof list2);
        memset(ind1, 0, sizeof ind1);
        memset(ind2, 0, sizeof ind2);
        memset(p1, -1, sizeof p1);
        memset(p2, -1, sizeof p2);
    }
    int main(){
        init();
        scanf("%d%d", &n, &m);
        int index1 = 0;
        int index2 = 0;
        for(int i = 0; i < m; i ++){
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            ind1[v] ++;
            list1[index1].to = v;
            list1[index1].w = w;
            list1[index1].id = i + 1;
            list1[index1].next = p1[u];
            p1[u] = index1 ++;
    
            ind2[u] ++;
            list2[index2].to = u;
            list2[index2].w = w;
            list2[index2].id = i + 1;
            list2[index2].next = p2[v];
            p2[v] = index2 ++;
        }
        criticalpath();
        return 0;
    }
    /*
    9 11
    0 1 6
    0 2 4
    0 3 5
    1 4 1
    2 4 1
    3 5 2
    4 6 9
    4 7 7
    5 7 4
    6 8 2
    7 8 4
    
    a1 : 0->1
    a4 : 1->4
    a8 : 4->7
    a7 : 4->6
    a10  6->8
    a11 : 7->8
    */
  • 相关阅读:
    数据结构与算法的思维导图
    第九周知识总结
    第八周知识总结
    作业七:问卷调查

    图的基本概念及基本术语
    二叉树

    队列

  • 原文地址:https://www.cnblogs.com/louzhang/p/2618043.html
Copyright © 2020-2023  润新知