08-图8 How Long Does It Take(25 分)

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 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
#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
#include<string>
#include<map>
#include<queue>
#include<functional>

using namespace std;
//ifstream inFile("C:\\Users\\DELL\\Desktop\\in.txt", ios::in);
const int MaxVertexNum = 100;
typedef int Vertex;
typedef int WeightType;
typedef char DatatType;

//边的定义
typedef struct ENode *PtrToENode;
struct ENode {
	Vertex V1, V2;
	WeightType Weight;
};
typedef PtrToENode Edge;

//邻接点的定义
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode {
	WeightType Weight;
	int earlisttime;//最早完成时间
	int lasttime;//最后完成时间
	Vertex AdjV;
	PtrToAdjVNode Next;
};

//顶点表头结点的定义
typedef struct VNode {
	int earlisttime;//最早完成时间
	PtrToAdjVNode FirstEdge;
	DatatType Data;
}AdjList[MaxVertexNum];


//图结点的定义
typedef struct GNode* PtrToGNode;
struct GNode {
	int Nv;
	int Ne;
	AdjList G;
};
typedef  PtrToGNode LGraph;


LGraph CreateGraph(int VertexNum)
{
	LGraph Graph = new GNode;
	Graph->Nv = VertexNum;
	Graph->Ne = 0;
	for (int i = 0; i < Graph->Nv; ++i) {
		Graph->G[i].FirstEdge = nullptr;
		Graph->G[i].earlisttime = 0;
	}
	return Graph;
}


//插入有向边<V1,V2>
void InsertEdge(LGraph Graph, Edge E)
{
	PtrToAdjVNode p = new AdjVNode;
	p->AdjV = E->V2;
	p->Weight = E->Weight;
	p->earlisttime = 0;
	p->Next = Graph->G[E->V1].FirstEdge;
	Graph->G[E->V1].FirstEdge = p;
}
LGraph BulidGraph()
{
	int Nv;
	cin >> Nv;
	LGraph Graph = CreateGraph(Nv);
	cin >> Graph->Ne;
	if (Graph->Ne) {
		Edge E = new ENode;
		for (int i = 0; i < Graph->Ne; ++i) {
			cin >> E->V1 >> E->V2 >> E->Weight;
			InsertEdge(Graph, E);
		}
	}
	return Graph;
}
void Print(LGraph Graph)
{
	if (Graph->Nv) {
		for (int i = 0; i < Graph->Nv; ++i) {
			PtrToAdjVNode p = Graph->G[i].FirstEdge;
			while (p) {
				cout << p->AdjV << " ";
				p = p->Next;
			}
			cout << endl;
		}
	}
}


bool TopSort(LGraph Graph, Vertex TopOrder[],int& ret,int m[])
{
	
	ret = 0;
	//对Graph进行拓扑排序,TopOrder[]顺序存储排序后的顶点下标
	int Indegree[MaxVertexNum], cnt;
	queue<int> Q;
	//初始化Indegree[]
	for (int V = 0; V < Graph->Nv; ++V) {
		Indegree[V] = 0;
	}
	//遍历图得到Indegree[]
	for (int V = 0; V < Graph->Nv; ++V) {
		for (PtrToAdjVNode W = Graph->G[V].FirstEdge; W; W=W->Next ) {
			Indegree[W->AdjV]++;//对有向边<V,W->AdjV>累计终点的入度
		}
	}
	//将所有入度为0的点入队
	for (int V = 0; V < Graph->Nv; ++V) {
		if (Indegree[V] == 0) {
			Q.push(V);
		}
	}
	//下面进行拓扑排序
	cnt = 0;
	while (Q.size()) {
		int V = Q.front();//弹出一个入度为0的点
		Q.pop();
		TopOrder[cnt++] = V;//将之存为结果序列的下一个元素
		//对V的每个邻接点W->AdjV
		for (PtrToAdjVNode W = Graph->G[V].FirstEdge; W; W = W->Next) {
			if (--Indegree[W->AdjV] == 0) {//若删除V使得W->AdjV入度为零
				Q.push(W->AdjV );
			}
			if (Graph->G[V].earlisttime + W->Weight >W->earlisttime) {
				W->earlisttime = Graph->G[V].earlisttime  + W->Weight;
				Graph->G[W->AdjV ].earlisttime = W->earlisttime;
				m[W->AdjV] = ret;
				if (ret < W->earlisttime) {
					ret = W->earlisttime;
				}
			}
		}
	}
	if (cnt != Graph->Nv) {
		return false;//说明图中有回路,返回不成功的标志
	}
	else {
		return true;
	}
}
int main()
{
	LGraph Graph = BulidGraph();
	//Print(Graph);
	Vertex TopOrder[MaxVertexNum] ;
	Vertex m[MaxVertexNum];
	int ret = 0;
	if (TopSort(Graph, TopOrder,ret,m)) {
		cout << ret << endl;
	}
	else {
		cout << "Impossible" << endl;
	}

	//delete Graph;
//	inFile.close();
	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值