How Long Does It Take
How Long Does It Take
Given the relations of all the activities of a project, you are supposed to find the earliest completion time of the project.
Input Specification:
Each input file contains one test case. Each case starts with a line containing two positive integers N (≤ 100), the number of activity check points (hence it is assumed that the check points are numbered from 0 to N−1), and M, the number of activities. Then M lines follow, each gives the description of an activity. For the i -th activity, three non-negative numbers are given: S[i] , E[i] , and L[i] , where S[i] is the index of the starting check point, E[i] of the ending check point, and L[i] the lasting time of the activity. The numbers in a line are separated by a space.
Output Specification:
For each test case, if the scheduling is possible, print in a line its earliest completion time; or simply output "Impossible".
Sample Input 1:
9 12 0 1 6 0 2 4 0 3 5 1 4 1 2 4 1 3 5 2 5 4 0 4 6 9 4 7 7 5 7 4 6 8 2 7 8 4
Sample Output 1:
18
Sample Input 2:
4 5 0 1 1 0 2 2 2 1 3 1 3 4 3 2 5
Sample Output 2:
Impossible
解题思路
这道题其实就是求完成所有活动的最短时间,也就是找一条从源点到终点的带权路径长度最长的路径,即关键路径,这条路径的权值就是所有活动完成的最早时间。
只需要在拓扑排序的基础上稍作修改。求最长距离和Dijkstra算法很像,用一个dist数组来记录到点i的最长距离。每次从队列弹出入度为0的点v,扫描一遍与该点相邻的点,如果发现dist[v]与点v到相邻点这条边的权值的和比原来的dist[i]大,就更新dist[i]为最大的那个值。
其中如果发现这个图有环,也就是弹出的顶点个数与图中顶点个数不相同,就说明没有关键路径。
AC代码如下:
1 #include <cstdio> 2 #include <iostream> 3 #include <vector> 4 #include <queue> 5 #include <algorithm> 6 7 struct Edge { 8 int to, wt; 9 }; 10 11 struct Graph { 12 std::vector<std::vector<Edge> > G; 13 int verN, edgeN; 14 }; 15 16 Graph *createGraph(int n, int m); 17 void topSort(Graph *graph); 18 19 int main() { 20 int n, m; 21 scanf("%d %d", &n, &m); 22 Graph *graph = createGraph(n, m); 23 topSort(graph); 24 25 return 0; 26 } 27 28 Graph *createGraph(int n, int m) { 29 Graph *graph = new Graph; 30 graph->verN = n; 31 graph->edgeN = m; 32 graph->G.resize(graph->verN); 33 34 for (int i = 0; i < graph->edgeN; i++) { 35 int v, w, wt; 36 scanf("%d %d %d", &v, &w, &wt); 37 graph->G[v].push_back({w, wt}); 38 } 39 40 return graph; 41 } 42 43 void topSort(Graph *graph) { 44 int indeg[graph->verN] = {0}, time[graph->verN], cnt = 0; 45 std::fill(time, time + graph->verN, -1); 46 for (int v = 0; v < graph->verN; v++) { 47 for (std::vector<Edge>::iterator it = graph->G[v].begin(); it != graph->G[v].end(); it++) { 48 indeg[it->to]++; 49 } 50 } 51 52 std::queue<int> q; 53 for (int v = 0; v < graph->verN; v++) { 54 if (indeg[v] == 0) { 55 q.push(v); 56 time[v] = 0; 57 } 58 } 59 while (!q.empty()) { 60 int v = q.front(); 61 q.pop(); 62 cnt++; 63 for (std::vector<Edge>::iterator it = graph->G[v].begin(); it != graph->G[v].end(); it++) { 64 if (--indeg[it->to] == 0) q.push(it->to); 65 time[it->to] = std::max(time[v] + it->wt , time[it->to]); 66 } 67 } 68 69 if (cnt == graph->verN) { 70 int maxId = 0; 71 for (int v = 1; v < graph->verN; v++) { 72 if (time[v] > time[maxId]) maxId = v; 73 } 74 printf("%d", time[maxId]); 75 } 76 else { 77 printf("Impossible"); 78 } 79 }
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/14819863.html