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 TopologicalPath() 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][v].w < vl[u]) 55 vl[u] = vl[v] - adj[u][v].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[n-1]; //返回关键路径长度 81 }
相关练习
- 更新后的大纲把动态规划都删除了,但关键路径还留着,虽然一直没考过,说不准哪天就考了呢。
Source:
题目描述
描述:
图的连接边上的数据表示其权值,带权值的图称作网。
上图可描述为顶点集为(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<vector> 3 #include<string> 4 #include<map> 5 #include<stack> 6 #include<queue> 7 #include<iostream> 8 #include<algorithm> 9 using namespace std; 10 const int M=20; 11 string st; 12 map<string,int> mp; 13 int n,m,in[M],ve[M],vl[M]; 14 struct node 15 { 16 int v; //弧头 17 int w; //边权 18 node(int _v,int _w): v(_v),w(_w) {} 19 }; 20 vector<node> adj[M]; 21 stack<int> topOrder; 22 23 void TopologicalSort() 24 { 25 queue<int> q; 26 for(int i=0; i<n; i++) 27 if(in[i]==0) 28 q.push(i); 29 while(!q.empty()) 30 { 31 int u=q.front(); 32 topOrder.push(u); 33 q.pop(); 34 for(int i=0; i<adj[u].size(); i++) 35 { 36 node v = adj[u][i]; 37 in[v.v]--; 38 if(in[v.v]==0) 39 q.push(v.v); 40 if(ve[u]+v.w > ve[v.v]) 41 ve[v.v] = ve[u]+v.w; 42 } 43 } 44 } 45 46 int CriticalPath() 47 { 48 fill(ve,ve+n,0); 49 TopologicalSort(); 50 51 int s,t,maxLength=0; 52 for(int i=0; i<n; i++) 53 if(ve[i]==0){ 54 s=i;break; 55 } 56 for(int i=0; i<n; i++) 57 if(ve[i] > maxLength){ 58 maxLength=ve[i];t=i; 59 } 60 fill(vl,vl+n,maxLength); 61 62 while(!topOrder.empty()) 63 { 64 int u=topOrder.top(); 65 topOrder.pop(); 66 for(int i=0; i<adj[u].size(); i++) 67 { 68 node v = adj[u][i]; 69 if(vl[v.v]-v.w < vl[u]) 70 vl[u] = vl[v.v]-v.w; 71 } 72 } 73 74 vector<int> path[M]; 75 for(int u=0; u<n; u++) 76 { 77 for(int i=0; i<adj[u].size(); i++) 78 { 79 node v = adj[u][i]; 80 if(ve[u] == vl[v.v]-v.w) 81 path[u].push_back(v.v); 82 } 83 } 84 while(s != t) 85 { 86 printf("(%c,%c) ", st[s],st[path[s][0]]); 87 s=path[s][0]; 88 } 89 90 return ve[n-1]; 91 } 92 93 int main() 94 { 95 #ifdef ONLINE_JUDGE 96 #else 97 freopen("Test.txt", "r", stdin); 98 #endif // ONLINE_JUDGE 99 100 string c1,c2; 101 int k,v1,v2,w; 102 scanf("%d", &k); 103 while(k--) 104 { 105 for(int i=0; i<M; i++) 106 adj[i].clear(); 107 fill(in,in+M,0); 108 109 scanf("%d%d", &n,&m); 110 cin >> st; 111 for(int i=0; i<n; i++) 112 mp[st.substr(i,1)]=i; 113 for(int i=0; i<m; i++) 114 { 115 cin >> c1 >> c2 >> w; 116 v1 = mp[c1]; 117 v2 = mp[c2]; 118 adj[v1].push_back(node(v2,w)); 119 in[v2]++; 120 } 121 printf("%d\n", CriticalPath()); 122 } 123 124 return 0; 125 }