关键路径

  1 #include"iostream"
  2 #include"string"
  3 #include"stack"
  4 using namespace std;
  5 typedef string element;
  6 struct ArcNode{        //边结点
  7     int weight;
  8     int adjuex;
  9     ArcNode *nextarc;
 10 };
 11 struct VNode{        //顶点结点
 12     element data;
 13     ArcNode *firstarc;
 14 };
 15 
 16 class Graph{
 17 private:
 18     VNode *vertex;
 19     int vernum,arcnum;
 20 public:
 21     Graph(int vernum,int arcnum){
 22         this->vernum = vernum;
 23         this->arcnum = arcnum;
 24         vertex = new VNode[vernum];
 25         for(int i = 0;i < vernum;i++){
 26             vertex[i].firstarc = NULL;
 27         }
 28     }
 29     int connected(element e){
 30         for(int i = 0;i < vernum;i++){
 31             if(e == vertex[i].data){
 32                 return i;
 33             }
 34         }
 35         cout<<"没有该顶点"<<endl;
 36         return -1;
 37     }
 38     void cinCreate(){
 39         cout<<"输入"<<vernum<<"个顶点"<<endl;
 40         for(int i = 0;i < vernum;i++){
 41             cin>>vertex[i].data;
 42         }
 43         cout<<"输入"<<arcnum<<"条边"<<endl;
 44         element v1,v2;
 45         int n1,n2;
 46         for(i = 0;i < arcnum;i++){
 47             cin>>v1>>v2;
 48             n1 = connected(v1);
 49             n2 = connected(v2);
 50             ArcNode *p = new ArcNode;
 51             p->adjuex = n2;
 52             cin>>p->weight;
 53             p->nextarc = vertex[n1].firstarc;
 54             vertex[n1].firstarc = p;
 55         }
 56     }
 57     void show(){
 58         for(int i = 0;i < vernum;i++){
 59             ArcNode *p = vertex[i].firstarc;
 60             while(p){
 61                 cout<<"<"<<vertex[i].data<<", "<<vertex[p->adjuex].data<<">"<<" : "<<p->weight<<endl;
 62                 p = p->nextarc;
 63             }
 64         }
 65     }
 66     void topoSort(int *arr){
 67         stack<int> s;
 68         //初始化indegree数组
 69         int *indegree = new int[vernum];
 70         for(int i = 0;i < vernum;i++){
 71             indegree[i] = 0;
 72         }
 73         for(i = 0;i < vernum;i++){
 74             ArcNode *p = vertex[i].firstarc;
 75             while(p){
 76                 indegree[p->adjuex]++;
 77                 p = p->nextarc;
 78             }
 79         }
 80         //入度为0的点入栈
 81         for(i = 0;i < vernum;i++){
 82             if(!indegree[i]){
 83                 s.push(i);
 84             }
 85         }
 86         //其他为0点入栈
 87         for(i = 0;i < vernum;i++){
 88             arr[i] = s.top();
 89             s.pop();
 90             ArcNode *p = vertex[arr[i]].firstarc;
 91             while(p){
 92                 if(!--indegree[p->adjuex]){
 93                     s.push(p->adjuex);
 94                 }
 95                 p = p->nextarc;
 96             }
 97         }
 98     }
 99     void shortPath(){
100         //调用拓扑排序 排列顺序
101         int *topolist = new int[vernum];
102         topoSort(topolist);
103 
104         //最早发生时间ve
105         int *ve = new int[vernum];            
106         memset(ve,0,vernum * sizeof(int));        //初始化,int型只能初始化为0或-1
107         for(int i = 0;i < vernum;i++){            //遍历所有结点
108             int k = topolist[i];                //依次取出拓扑序列
109             ArcNode *p = vertex[k].firstarc;    //p指向k的邻接点
110             while(p){                            //邻接点存在
111                 int j = p->adjuex;                //邻接点的位置(下标)
112                 //在所有最早的时间中找到一个最迟的,(等待最迟的完成)代表该点的最早
113                 if(ve[j] < ve[k] + p->weight){    //若k的最早时间 加 k到j 的时间 比j 的最早时间迟,存上最长时间(因为j点要等待它前面所有点完成,即时间最长的完成)
114                     ve[j] = ve[k] + p->weight;    //ve[j]存上最早时间
115                 }
116                 p = p->nextarc;
117             }
118         }
119 
120         //最晚发生时间vl
121         int *vl = new int[vernum];
122         for(i = 0;i < vernum;i++){                //初始化为汇点的最早时间
123             vl[i] = ve[vernum - 1];
124         }
125         for(i = vernum - 1;i >= 0;i--){
126             int k = topolist[i];
127             ArcNode *p = vertex[k].firstarc;
128             while(p){
129                 int j = p->adjuex;                //邻接点
130                 if(vl[k] > vl[j] - p->weight){    //若j最迟时间 减 k到j的时间 比 k的最迟时间早,存最早(在所有最迟时间中找到一个最早的作为最迟时间,以保证所有的都不会迟到)
131                     vl[k] = vl[j] - p->weight;
132                 }
133                 p = p->nextarc;
134             }
135         }
136 
137         //判断某活动是否为关键活动
138         for(i = 0;i < vernum;i++){
139             ArcNode *p = vertex[i].firstarc;
140             while(p){
141                 int j = p->adjuex;            //邻接点
142                 int e = ve[i];                //最早活动
143                 int l = vl[j] - p->weight;    //(最迟活动)邻接点最迟时间 减 i到j的时间
144                 if(e == l){            //相等则为关键路径
145                     cout<<"<"<<vertex[i].data<<", "<<vertex[j].data<<">"<<ends;
146                 }
147                 p = p->nextarc;
148             }
149         }
150         cout<<endl;
151     }
152 };
153 /*
154 
155 v1 v2 v3 v4 v5 v6
156 v1 v2 6  v3 v1 1  v1 v4 5  v2 v5 3  v6 v4 2  v3 v2 5  v3 v4 5  v6 v3 4  v3 v5 6  v5 v6 6
157 
158 v0 v1 v2 v3 v4 v5 v6 v7 v8
159 v0 v1 6  v0 v2 4  v0 v3 5  v1 v4 1  v2 v4 1  v3 v5 2  v4 v6 9  v4 v7 7  v5 v7 4  v6 v8 2  v7 v8 4
160 */
161 int main(){
162     Graph g(9, 11);
163     g.cinCreate();
164 //    g.show();
165     g.shortPath();
166 
167     return 0;
168 }
BY oleolema
原文地址:https://www.cnblogs.com/oleolema/p/9027238.html