求关键路径

142 篇文章 0 订阅

     这问题几乎耗了我一下午的时间,一开始自己用邻接矩阵求,但求着求着就感到不对劲了,我怎么知道我所求得这个顺序就是数据所表示的图的顺序呢?我的ve,vl,ee,el是根据什么样的顺序求得呢?好像我自己都不知道。。。

         想了想还得是要按拓扑序来做,但我所知道的拓扑序没有权值,而且也只是会输出一个序列而已,存储序列很简单,但要怎么利用存储的这个序列求这四个数组呢?

         最后实在是有点烦了,看了题解,也是用邻接矩阵求的,而且也实现了利用拓扑序求ve,vl数组,然后只要看看ve和vl中的数组相等的下标所构成的序列就是关键路径(前提只有一条关键路径),为什么可以不用求ee和el呢?其实我们想一下,ee是活动a[i](a[i]是由<k1,j1>表示)最早的开始时间,那么ee[i]就是ve[k1],而el是活动a[i](a[i]是由<k2,j2>表示),那么el[i]就是vl[j2]-edge[k2][j2];

如果第i条边是关键活动的话,那么他是ee[i]==el[i];也就是ve[k1]==vl[j2]-edge[k2][j2],而k1==k2,j1==j2,所以前面那个式子就是ve[k1]+edge[k1][j1]==vl[j1],即ve[j1]==vl[j1];

所以只要求出ve和vl中的数组相等的下标所构成的序列即可,这个序列就是关键路径

题解:关键路径_PeterCuiy-CSDN博客_关键路径

#include<bits/stdc++.h>
using namespace std;
int main(){
    //freopen("in.txt","r",stdin);
    int mp[110][110];
    memset(mp,-1,sizeof(mp));
    int a,b,val,v,l;
    cin>>v>>l;
    for(int i=1;i<=l;i++){//邻接矩阵
        cin>>a>>b>>val;
        mp[a][b]=val;
    }
    int k;
    int in[110],out[110],ve[110],vl[110];
    memset(ve,0,sizeof(ve));
    for(int i=1;i<=v;i++){//计算入度
        k=0;
        for(int j=1;j<=v;j++){
            if(mp[j][i]!=-1)
                k++;
        }
        in[i]=k;
    }
    for(int i=1;i<=v;i++){//计算出度
        k=0;
        for(int j=1;j<=v;j++){
            if(mp[i][j]!=-1)
                k++;
        }
        out[i]=k;
    }
    for(int i=1;i<=v;i++){//顺拓扑序求ve数组
        if(in[i]==0){
            for(int j=1;j<=v;j++){
                if(mp[i][j]!=-1){
                    ve[j]=max(ve[j],mp[i][j]+ve[i]);
                    in[j]--;
                }
            }
        }
    }
    k=v;
    for(int i=1;i<=v;i++) vl[i]=ve[k];
    //将vl中的每个顶点初始化为最后一个顶点的值
    //因为最后一个顶点是最大值,到后面好更新
    for(int i=k;i>=1;i--){//逆拓扑序求vl
        if(out[i]==0){
            for(int j=1;j<=v;j++){
                if(mp[j][i]!=-1){
                    vl[j]=min(vl[j],vl[i]-mp[j][i]);
                    out[j]--;
                }
            }
        }
    }
    cout << "****************************\n";
        cout << "Ve数组:";
        for(int i = 1; i <= k; i++){
            cout << ve[i] << " ";
        }
        cout << endl;
        cout << "Vl数组:";
        for(int i = 1; i <= k; i++){
            cout << vl[i] << " ";
        }
        cout << "\n****************************\n";
        cout<<"关键路径"<<endl;
    for(int i=1;i<=k;i++){
        if(ve[i]==vl[i]){
            cout<<'v'<<i<<" ";
        }

    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

killer_queen4804

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值