关键路径

关键路径是基于拓扑排序的一种算法,网上有很多介绍,我就不过多介绍了。

关键在于代码,代码写的很魔性,但是我有打注释,可以参考。

关键路径的关键是找出这个活动的最早开始时间和最晚开始时间,当最早和最晚相等时,这就是一个关键点了。把所有关键点连接起来而且联通起点和终点的路径就是关键路径,但是关键路径可能不只有一条。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<stack>
 4 using namespace std;
 5 
 6 int map[1000][1000],in[1000],out[1000]; 
 7 //map是记录边的权值,in是某一个点的入度数,out是出度数 
 8 int a[1000][1000],b[1000][1000],in1[1000];
 9 //a和上一篇拓扑排序里的意思一样,b是反着来的,in1是临时变量。 
10 int later[1000],size=0,ans[1000];
11 //later就是最晚的开始时间,size是找到的路径长度,ans是储存路径 
12 int N,M,star,end;
13 //N点数,M边数,star开始点,end结束点 
14 stack<int> sk1;
15 
16 void pt1()
17 { 
18    for(int i=size;i>=1;i--){
19       printf("%d ",ans[i]);
20    }
21    cout<<end;
22    cout<<endl;
23 }
24 
25 void DFS(int x)
26 {
27    
28    if(x==star)pt1();  //如果找到开始点就结束输出一条关键路径 
29    for(int i=1;i<=in[x];i++){
30       if( later[x]-map[x][b[x][i]]==later[b[x][i]] ){
31          //关键路径的判断:最晚开始时间减去权值=上一个最晚的开始时间 
32          size++;
33          ans[size]=b[x][i];
34          DFS(b[x][i]);
35          size--;
36       }
37    }
38 }
39 
40 void right()
41 {
42    while(!sk1.empty()){  //正这找拓扑序 
43       int x=sk1.top();
44       sk1.pop();
45       for(int i=1;i<=out[x];i++){
46          later[ a[x][i] ]=max( later[ a[x][i] ] , later[x]+map[x][a[x][i]] );
47          //记录最晚开始时间,之前的最晚开始时间和现在的最晚开始时间做比较 
48          in1[ a[x][i] ]--; //减去下一个点的入度 
49          if(!in1[ a[x][i] ]) //如果下一个点的入度变为0,就入队,等待下次搜 
50             sk1.push(a[x][i]);
51       }
52    }
53 }
54 
55 void init()
56 {
57    int aa,bb,cc;
58    cin>>N>>M;
59    for(int i=1;i<=M;i++){
60       scanf("%d%d%d%*c",&aa,&bb,&cc);
61       map[aa][bb]=cc;  //记录权值,以为只用来记录权值所以可以当无向边记录 
62       map[bb][aa]=cc;
63       in1[bb]++;    //在搜索拓扑序的时候减掉用 
64       a[aa][++out[aa]]=bb;  //aa点的第x个出度是bb 
65       b[bb][++in[bb]]=aa;  //bb点的第x个入度是aa 
66    }
67    for(int i=1;i<=N;i++){  //找起点和结束点 
68       if(out[i]==0)end=i;
69       if(in[i]==0)star=i;
70    }
71    sk1.push(star);
72 }
73 
74 int main()
75 {
76    init(); //初始化 
77    right(); //关键路径,顺便记录later 
78    DFS(end); //搜索关键路径 
79    system("pause");
80    return 0;
81 } 

 

posted on 2016-11-08 09:38  fuyun_boy  阅读(392)  评论(0编辑  收藏  举报

导航