一条有向边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\n"); 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 */
时间: 2024-10-26 16:40:24