求关键活动和关键路径


#include 
#include 
#include 
#include 
using namespace std;
const int N = 210,M=N;

int h[N], e[M], ne[M], idx, t[N], d[N], f[M], be[M], w[M];
int ear[N],lat[N];
int n, m;
int q[N];

void add(int a, int b, int c)  // 添加一条边a->b,边权为c
{
    e[idx] = b, w[idx] = c, ne[idx] = h[a], be[idx] = t[b], h[a] = idx, f[idx] = a, d[b]++, t[b] = idx ++ ;
}

bool topsort()
{
    int hh = 0, tt = -1;
    for (int i = 1; i <= n; i ++ )
        if (!d[i])
            q[ ++ tt] = i;
    while (hh <= tt)
    {
        int t = q[hh ++ ];

        for (int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (-- d[j] == 0)
                q[ ++ tt] = j;
        }
    }
    
    return tt==n-1;
}

void find_ear(int pos){
    if(ear[pos]) return ;
    
    int Max=0;
    for(int i=t[pos];i!=-1;i=be[i]){
        int j=f[i];
        find_ear(j);
        Max=max(Max,ear[j]+w[i]);
    }
    
    ear[pos]=Max;
    
    return ;
}

void find_lat(int pos){
    if(lat[pos]) return ;
    
    int Min=0x3f3f3f3f;
    for(int i=h[pos];i!=-1;i=ne[i]){
        int j=e[i];
        find_lat(j);
        Min=min(Min,lat[j]-w[i]);
    }
    
    lat[pos]=Min;
    
    return ;
}

int main()
{
    cin>>n>>m;
    memset(h, -1, sizeof h);
    memset(t, -1, sizeof t);

    for(int i=0;i){
        int a, b, c;
        cin>>a>>b>>c;
        add(a, b, c);
    }
    
    if(!topsort()) {
        cout<<"unworkable project";
        return 0;
    }
    else {
        ear[q[0]]=0;
        find_ear(q[n-1]);
        lat[q[n-1]]=ear[q[n-1]];
        find_lat(q[0]);
    }
    
    cout<1]]<<endl;
    
    for(int j=1;j<=n;j++){
        vector<int> ans;
        for(int i=h[j];~i;i=ne[i]){
            int k=e[i];
            if(ear[j]+w[i]==lat[k]) ans.push_back(k);
        }
        sort(ans.begin(),ans.end());
        for(auto x: ans){
           cout<"->"<endl;
        }
    }
    
    return 0;
}

题目链接:https://pintia.cn/problem-sets/1466546146369536000/problems/1466547816000323584

相关