关键路径分析

一条有向边E,权值为EdgeValue,点i指向点j,称呼点i为始点,点j为终点。

 

事件最早发生时间ve:只要始点(多个)都已准备好就立即行动,即选择始点(多个)中最早发生时间最晚的

ve(j)=max{ve(i)+EdgeValue}

 

事件最晚发生时间vl:选择事件最晚发生时间,使终点(多个)到达后刚好不会发生问题,即选择终点(多个)中最晚发生时间最早的

vl(i)=min{vl(j)-EdgeValue}

 

活动最早发生时间l:只要始点(一个)都已准备好就立即行动,即选择始点(一个)最早发生时间

l(E)=vl(i)

 

活动最晚发生时间e:选择事件最晚发生时间,使终点(一个)到达后刚好不会发生问题,即选择终点(一个)中最晚发生时间最早的

e(E)=ve(j)-EdgeValue

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <malloc.h>
  4 #define maxn 1000
  5 
  6 struct node
  7 {
  8     long d; //
  9     long value; //边权值
 10     struct node *next;
 11 }*in[maxn+1],*out[maxn+1];
 12 //in:某点作为边的终点,所有对应边的始点
 13 //out:某点作为边的始点,所有对应边的终点
 14 //编号为k的边的始点和终点为x[k]和y[k],权值为z[k]
 15 //点k的出度为g[k]
 16 //队列为q
 17 //ve(early),vl(late),e,l分别为事件最早,最晚发生时间,活动最早,最晚发生时间
 18 long x[maxn+1],y[maxn+1],z[maxn+1],g[maxn+1],q[maxn+1],ve[maxn+1],vl[maxn+1],e[maxn+1],l[maxn+1];
 19 
 20 long max(long a,long b)
 21 {
 22     if (a>b)
 23         return a;
 24     else
 25         return b;
 26 }
 27 
 28 long min(long a,long b)
 29 {
 30     if (a>b)
 31         return b;
 32     else
 33         return a;
 34 }
 35 
 36 int main()
 37 {
 38     long n,m,head,tail,i,s,t;
 39     struct node *p;
 40     scanf("%ld%ld",&n,&m);
 41     //init
 42     for (i=1;i<=n;i++)
 43         g[i]=0;
 44     for (i=1;i<=m;i++)
 45     {
 46         scanf("%ld%ld%ld",&x[i],&y[i],&z[i]);
 47         g[y[i]]++;
 48         p=(struct node *) malloc (sizeof(struct node));
 49         p->d=y[i];
 50         p->value=z[i];
 51         p->next=out[x[i]];
 52         out[x[i]]=p;
 53     }
 54 
 55     head=0;
 56     tail=0;
 57     for (i=1;i<=n;i++)
 58         if (g[i]==0)
 59         {
 60             tail++;
 61             q[tail]=i;
 62         }
 63 
 64     //init
 65     for (i=1;i<=n;i++)
 66         ve[i]=0;
 67     while (head<tail)
 68     {
 69         head++;
 70         s=q[head];
 71         p=out[s];
 72         while (p!=NULL)
 73         {
 74             t=p->d;
 75             g[t]--;
 76             ve[t]=max(ve[t],ve[s]+p->value);
 77             if (g[p->d]==0)
 78             {
 79                 tail++;
 80                 q[tail]=p->d;
 81             }
 82             p=p->next;
 83         }
 84     }
 85     if (tail<n)
 86     {
 87         printf("has loop
");
 88         exit(1);
 89     }
 90 
 91     //init
 92     for (i=1;i<=n;i++)
 93         vl[i]=2000000000;
 94     vl[q[tail]]=ve[q[tail]];
 95     for (i=tail;i>=1;i--)
 96     {
 97         s=q[i];
 98         p=out[s];
 99         while (p)
100         {
101             vl[s]=min(vl[s],vl[p->d]-p->value);
102             p=p->next;
103         }
104     }
105 
106     for (i=1;i<=m;i++)
107     {
108         e[i]=ve[x[i]];
109         l[i]=vl[y[i]]-z[i];
110     }
111     for (i=1;i<=m;i++)
112         if (e[i]==l[i])
113             printf("%ld ",i);
114     return 0;
115 }
116 /*
117 9 11
118 7 9 2
119 8 9 4
120 5 7 8
121 5 8 7
122 6 8 4
123 2 5 1
124 3 5 1
125 4 6 2
126 1 2 6
127 1 3 4
128 1 4 5
129 */
原文地址:https://www.cnblogs.com/cmyg/p/6979771.html