關鍵路徑


Date:2019-06-17 17:47:15

算法思想

 1 //Vi ---- ar ---> Vj
 2 
 3 int e[r];   //活動ar的最早開始時間
 4 int l[r];   //活動ar的最晚開始時間
 5 int ve[i];  //事件vi的最早發生時間
 6 int vl[i];  //事件vi的最晚發生時間
 7 
 8 e[r] = ve[i];   //活動ar的最早開始時間 = 事件vi的最早發生時間
 9 l[r] = vl[r]-w[r]; //活動ar的最晚開始時間 = 時間vj的最晚發生時間 - ar的邊權
10 
11 
12 ve[j] = max{ve[ik] + w[rk]};  //Vj結點的最早發生時間 = Max{前驅結點Vik的最早發生時間+活動aik的邊權}
13 //若解決Vj,必先解決Vi --> 拓撲排序求解ve
14 vl[i] = min(vl[jk] - w[rk]);  //Vi結點的最晚發生時間 = Min{后繼結點Vjk的最晚發生時間 - 活動aik的邊權}
15 //若解決Vi,必先解決Vj --> 逆拓撲排序求解vl

算法實現

 1 stack<int> topOrder;
 2 int TopologicalSort()
 3 {
 4     queue<int> q;
 5     for(int i=0; i<n; i++)
 6         if(inDegree[i]==0)
 7             q.push(i);
 8     while(!q.empty())
 9     {
10         int u = q.front();
11         q.pop();
12         topOrder.push(u);   //u加入拓撲排序
13         for(int i=0; i<adj[u].size(); i++)
14         {
15             int v = adj[u][i].v;
16             inDegree[v]--;
17             if(inDegree[v]==0)
18                 q.push(v);
19             if(ve[u]+adj[u][i].w > ve[v])
20                 ve[v] = ve[u] + adj[u][i].w;    //求解ve
21         }
22     }
23     if(topOrder.size() != n)    return false;
24     else    return true;
25 }
26 
27 vector<int> path[M];    //多條關鍵路徑
28 int CriticalPath()
29 {
30     fill(ve, ve+n, 0);
31     if(topologicalSort() == false)
32         return -1;  //有環
33 
34     int s,t,maxLength=0;
35     for(int i=0; i<n; i++)
36         if(ve[i]==0){
37             s=i;break;  //源點,最早發生的事件
38         }
39 
40     for(int i=0; i<n; i++)
41         if(ve[i] > maxLength){
42             maxLength = ve[i];
43             t=i;        //匯點,最晚發生的事件
44         }
45     fill(vl, vl+n, maxLength);
46 
47     while(!topOrder.empty())
48     {
49         int u = topOrder.top();
50         topOrder.pop();
51         for(int i=0; i<adj[u].size(); i++)
52         {
53             int v = adj[u][i].v;
54             if(vl[v] - adj[u][i].w < vl[u])
55                 vl[u] = vl[v] - adj[u][i].w;
56         }
57     }
58 
59     for(int u=0; u<n; u++)
60     {
61         for(int i=0; i<adj[u].size(); i++)
62         {
63             int v = adj[u][i].v;
64             int w = adj[u][i].w;
65             int e = ve[u];      //活動的最早開始時間
66             int l = vl[v]-w;    //活動的最晚開始時間
67             if(e==l)
68                 path[u].push_back(v);
69         }
70     }
71 
72     printf("%d", s);
73     s=path[s][0];
74     while(s != t)
75     {
76         printf("->%d",s);   //輸出一條關鍵路徑
77         s=path[s][0];
78     }
79 
80     return ve[t];    //返回關鍵路徑長度
81 }

 

相關練習

  • 更新后的大綱把動態規划都刪除了,但關鍵路徑還留着,雖然一直沒考過,說不准哪天就考了呢。

Source:

Codeup 23132: 關鍵路徑

題目描述

描述:

圖的連接邊上的數據表示其權值,帶權值的圖稱作網。

上圖可描述為頂點集為(a,b,c,d,e)

邊集及其權值為(始點,終點 權值):

a b 3

a c 2 

b d 5

c d 7

c e 4

d e 6            

網的源點是入度為0的頂點,匯點是出度為0的頂點。網的關鍵路徑是指從源點到匯點的所有路徑中,具有最大路徑長度的路徑。上圖中的關鍵路徑為a->c->d->e,其權值之和為關鍵路徑的長度為15。

本題的要求是根據給出的網的鄰接矩陣求該網的關鍵路徑及其長度。

輸入

第一行輸入一個正整數n(1<=n<=5),其代表測試數據數目,即圖的數目

第二行輸入x(1<=x<=15)代表頂點個數,y(1<=y<=19)代表邊的條數

第三行給出圖中的頂點集,共x個小寫字母表示頂點

接下來每行給出一條邊的始點和終點及其權值,用空格相隔,每行代表一條邊。

輸出

第一個輸出是圖的關鍵路徑(用給出的字母表示頂點, 用括號將邊括起來,頂點逗號相隔)

第二個輸出是關鍵路徑的長度

每個矩陣對應上面兩個輸出,兩個輸出在同一行用空格間隔,每個矩陣的輸出占一行。

樣例輸入

2
5 6
abcde
a b 3
a c 2
b d 5
c d 7
c e 4
d e 6
4 5
abcd
a b 2
a c 3
a d 4
b d 1
c d 3

樣例輸出

(a,c) (c,d) (d,e) 15
(a,c) (c,d) 6

Code:

  1 #include<cstdio>
  2 #include<map>
  3 #include<stack>
  4 #include<queue>
  5 #include<vector>
  6 #include<algorithm>
  7 using namespace std;
  8 const int M=1e2;
  9 struct node
 10 {
 11     int v,w;
 12 };
 13 map<char,int> mp;
 14 stack<int> topOrder;
 15 vector<node> adj[M];
 16 vector<int> path[M];
 17 int k,n,m,inDegree[M],ve[M],vl[M];
 18 char str[M];
 19 
 20 void TopologicalSort()
 21 {
 22     queue<int> q;
 23     for(int i=0; i<n; i++)
 24         if(inDegree[i]==0)
 25             q.push(i);
 26     while(!q.empty())
 27     {
 28         int u = q.front();q.pop();
 29         topOrder.push(u);
 30         for(int i=0; i<adj[u].size(); i++)
 31         {
 32             int v = adj[u][i].v;
 33             inDegree[v]--;
 34             if(inDegree[v]==0)
 35                 q.push(v);
 36             if(ve[u]+adj[u][i].w > ve[v])
 37                 ve[v] = ve[u] + adj[u][i].w;
 38         }
 39     }
 40 }
 41 
 42 int CriticalPath()
 43 {
 44     fill(ve,ve+n,0);
 45     TopologicalSort();
 46 
 47     int s,t,maxLength=0;
 48     for(int i=0; i<n; i++)
 49         if(ve[i]==0){
 50             s=i;break;
 51         }
 52     for(int i=0; i<n; i++)
 53         if(ve[i]>maxLength){
 54             maxLength=ve[i];
 55             t=i;
 56         }
 57     fill(vl,vl+n,maxLength);
 58 
 59     while(!topOrder.empty())
 60     {
 61         int u = topOrder.top();
 62         topOrder.pop();
 63         for(int i=0; i<adj[u].size(); i++)
 64         {
 65             int v = adj[u][i].v;
 66             if(vl[v]-adj[u][i].w < vl[u])
 67                 vl[u] = vl[v]-adj[u][i].w;
 68         }
 69     }
 70 
 71     for(int u=0; u<n; u++)
 72     {
 73         for(int i=0; i<adj[u].size(); i++)
 74         {
 75             int v=adj[u][i].v;
 76             int w=adj[u][i].w;
 77             int e=ve[u];
 78             int l=vl[v]-w;
 79             if(e==l)
 80                 path[u].push_back(v);
 81         }
 82     }
 83 
 84     while(s != t)
 85     {
 86         printf("(%c,%c) ", str[s],str[path[s][0]]);
 87         s=path[s][0];
 88     }
 89     printf("%d\n", ve[t]);
 90 }
 91 
 92 int main()
 93 {
 94 #ifdef ONLINE_JUDGE
 95 #else
 96     freopen("Test.txt", "r", stdin);
 97 #endif // ONLINE_JUDGE
 98 
 99     scanf("%d", &k);
100     while(k--)
101     {
102         scanf("%d%d\n", &n,&m);
103         scanf("%s\n", str);
104 
105         mp.clear();
106         fill(inDegree,inDegree+M,0);
107         for(int i=0; i<n; i++)
108         {
109             adj[i].clear();
110             path[i].clear();
111         }
112 
113         for(int i=0; i<n; i++)
114             mp[str[i]]=i;
115         for(int i=0; i<m; i++)
116         {
117             int c1,c2,w;
118             scanf("%c %c %d\n", &c1,&c2,&w);
119             int v1=mp[c1], v2=mp[c2];
120             adj[v1].push_back(node{v2,w});
121             inDegree[v2]++;
122         }
123         CriticalPath();
124     }
125 
126     return 0;
127 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM