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 N1), 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 }

posted @ 2021-05-28 19:36  onlyblues  阅读(246)  评论(0编辑  收藏  举报
Web Analytics