08-图9 关键活动(30 分)

刚开始就拿一个点算,用栈操作
死活只有20分,还是老老实实用拓扑排序的求最晚时间的方法算
恶心的地方是关键路径有很多,,,,,,,,,,,,,
不说了,太难了

#include <bits/stdc++.h>
using namespace std;
#define Inf 2<<17
int A[10000][10000];
int Indegree[10000]={0};
int Outdegree[10000]={0};
int ETime[10000]={0};//最早完成
int LTime[10000]={0}; //最晚完成
int N,M;
int ECT;
int getMax(int a[]){//求一个数组的最大值
    int max=-1;
    for(int i=1;i<=N;i++){
        if(a[i]>max) max=a[i];
    }
    return max;
}
int TopSort(){
    int V,cnt=0;
    queue<int> q;
    for(int i=1;i<=N;i++){
        if(Indegree[i]==0){//找出所有入度为0的点,将他们push进队列中
            q.push(i);
        }
    }
    int temp;
    while(!q.empty()){
        temp=V=q.front(); //找到队列第一个元素
        q.pop();  //pop出来
        cnt++;
        for(int j=1;j<=N;j++){
            if(A[V][j]!=Inf){  //与该节点有关系的点
                if(ETime[V]+A[V][j]>ETime[j]){
                    ETime[j]=ETime[V]+A[V][j];//更新最早完成时间
                }
                if(--Indegree[j]==0){//如果度为0 
                    q.push(j); //把这个点放进队列里
                }
            }
        }
    }
    ECT=getMax(ETime);
    if(cnt!=N) return 0;
    return temp;
}
void late(){
    int V;
    queue<int> q;
    for(int i=1;i<=N;i++){
        LTime[i]=ECT;
        if(Outdegree[i]==0){//找出所有出度为0的点,将他们push进队列中
            q.push(i);
        }
    }
    while(!q.empty()){
        V=q.front(); //找到队列第一个元素
        q.pop();  //pop出来
        for(int i=1;i<=N;i++){
            if(A[i][V]!=Inf){  //与该节点有关系的点
                LTime[i]=min(LTime[i],LTime[V]-A[i][V]);
                if(--Outdegree[i]==0){//如果度为0 
                    q.push(i); //把这个点放进队列里
                }
            }
        }
    }
}
int main(){
    cin>>N>>M;
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++){
            A[i][j]=Inf;// 将每个值初始化为最大值
        }
    }
    for (int i = 0; i < M; ++i)//常规读取
    {
        int a,b;
        cin>>a>>b;
        cin>>A[a][b];  //修改完成工作的时间
        Indegree[b]++;
        Outdegree[a]++;
    }
    int k=TopSort();
    if(!k) printf("0\n");
    else{
        printf("%d\n",ECT);
        late();
        for(int i=1;i<=N;++i){
            // for(int j=1;j<=N;j++){
            for(int j=N;j>=1;j--){//关键活动输出的顺序规则是:任务开始的交接点编号小者优先,起点编号相同时,与输入时任务的顺序相反。
                if(A[i][j]!=Inf&&ETime[i]+A[i][j]==LTime[j]){
                    printf("%d->%d\n",i,j);
                }
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38677814/article/details/80143703
今日推荐