PAT 数据结构 06-图7. 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
定义结点node,有3个变量,最早可以开始的时间,入度(前驱结点个数),后继节点数组。
每个结点最早可以开始的时间受制于若干条前驱路径中花费时间最长的一条。
一开始入度为0的结点先进入队列。每次从队列中弹出一个结点作为当前结点进行处理,将其后继结点的入度减一,若为0则入队列,若当前结点的最早开始时间加上该结点到后继节点的路径时间大于后继节点原有的最早开始时间,则更新后继节点的最早开始时间。
/*2015.7.16cyq*/
#include <iostream>
#include <vector>
#include <queue>
#include <fstream>
using namespace std;

//ifstream fin("case1.txt");
//#define cin fin

struct node{
	int early;//最早可以开始的时间
	int inDegree;
	vector<int> next;
	node(int t,int d):early(t),inDegree(d){}
};

int main(){
	int N,M;
	cin>>N>>M;
	vector<vector<int> > edges(N,vector<int>(N,-1));
	vector<node> G(N,node(0,0));//结点数组
	int a,b,c;
	while(M--){
		cin>>a>>b>>c;
		edges[a][b]=c;
		G[a].next.push_back(b);
		G[b].inDegree++;
	}
	queue<int> q;
	int count=0;
	for(int i=0;i<N;i++){
		if(G[i].inDegree==0){//入度为0的结点
			G[i].early=0;//开始时间为0
			q.push(i);
			count++;
		}
	}
	while(!q.empty()){
		int cur=q.front();//当前结点序号
		q.pop();
		for(auto it=G[cur].next.begin();it!=G[cur].next.end();it++){
			if(G[cur].early+edges[cur][(*it)] > G[(*it)].early){
				G[(*it)].early=G[cur].early+edges[cur][(*it)];//更新最早可以开始的时间
			}
			if(--G[(*it)].inDegree==0){
				q.push(*it);
				count++;
			}	
		}
	}
	if(count!=N){//剩下的结点形成环,或者孤立
		cout<<"Impossible"<<endl;
		return 0;
	}
	int result=-1;
	for(int i=0;i<N;i++){
		if(G[i].early>result)
			result=G[i].early;
	}
	cout<<result<<endl;
	return 0;
}
    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/tuzigg123/article/details/46918273
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞