08-图8 How Long Does It Take(25 分)
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
//
// main.cpp
// TopSort
//
// Created by air on 2018/4/26.
// Copyright © 2018年 air. All rights reserved.
/*这道题是 Earliest[j] = max{Earliest[i] + C(i,j)};
利用拓扑排序进行改造
即使下一个邻接点的入度不为0,一样需要更新它的Earliest的值,只是不会入队,只有在入度为0的时候才可以入队
*/
#include <iostream>
#include <stack>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#define Infinity 1 << 30
using namespace std;
typedef int vertex;
typedef int degree;
typedef int weightType;
struct GNode{
vertex Nv;
vertex Ne;
int** map;
};
typedef struct GNode* ptrToGraph;
typedef ptrToGraph LGraph;
/*---------------------建立图----------------------*/
LGraph buildGraph(){
LGraph graph = new GNode;
cin >> graph->Nv >> graph->Ne;
/* 建立二维数组 */
graph->map = new vertex*[graph->Nv];
for(vertex i = 0; i < graph->Nv; i++)
graph->map[i] = new vertex[graph->Nv];
/* 一开始初始化成正无穷大*/
for(int i = 0; i < graph->Nv; i++){
for(int j = 0; j < graph->Nv; j++)
graph->map[i][j] = Infinity;
}
/* 数值初始化,有向图 */
vertex V1,V2;
weightType Weight;
for(int i = 0; i < graph->Ne; i++){
cin >> V1 >> V2 >> Weight;
graph->map[V1][V2] = Weight;
}
return graph;
}
/*---------------------拓扑排序----------------------*/
void TopSort(LGraph graph){
vertex i,j;
int cnt = 0;
queue<vertex> q;
int Indegree[graph->Nv];
int Earliest[graph->Nv];
for(i = 0; i < graph->Nv; i++){
Indegree[i] = 0;
Earliest[i] = 0;
}
for(i = 0; i < graph->Nv; i++){
for(j = 0; j < graph->Nv; j++){
if(graph->map[i][j] != Infinity)
Indegree[j] ++;
}
}
/* 一开始把入度为0的全部入队列 */
for(i = 0; i < graph->Nv; i++)
if(Indegree[i] == 0)
q.push(i);
while (! q.empty()) {
vertex temp = q.front();
q.pop();
cnt++;
for(i = 0; i < graph->Nv; i++){
if(graph->map[temp][i] != Infinity){
Earliest[i] = max(Earliest[i], Earliest[temp] + graph->map[temp][i]);
if((--Indegree[i]) == 0)
/* 这个if一定要在上一个if的下面,我一开始的错就在放一起了,所以导致一个测试点一直过不了 */
q.push(i); /* 入度为0才入队,并不是直接临接点就入队 */
}
}
}
/* 以下解决了多个起点和多个终点第四个评测点 */
int maxNumber = 0;
for(i = 0; i < graph->Nv; i++)
maxNumber = max(maxNumber,Earliest[i]);
if (cnt != graph->Nv)
cout << "Impossible" << endl;
else
cout << maxNumber << endl;
}
int main(int argc, const char * argv[]) {
LGraph graph = buildGraph();
TopSort(graph);
delete graph;
return 0;
}