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
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MaxVertexNum 105
#define INFINITY 65535
typedef int Vertex;
typedef int WeightType;
//邻接点的定义
typedef struct AdjaVNode * PtrToAdjaVNode;
struct AdjaVNode{
Vertex AdjaV;
WeightType Weight;
PtrToAdjaVNode Next;
};
//顶点表头结点的定义
typedef struct Vnode {
PtrToAdjaVNode FirstEdge;
//DataType Data;//如果顶点需要存储数据
}AdjaList[MaxVertexNum];
//图结点的定义
typedef struct GNode * PtrToGNode;
struct GNode {
int Nv;
int Ne;
AdjaList G;//邻接表为一个结构数组
};
typedef PtrToGNode LGraph;
//边的定义
typedef struct ENode * PtrToENode;
struct ENode {
Vertex V1,V2;
WeightType Weight;
};
typedef PtrToENode Edge;
//队列的节点
typedef Vertex ElementType;
struct QNode{
ElementType Element;
struct QNode * Next;
};
//队列的空头节点,含有指向头尾的指针
struct HeaderQNode{
struct QNode * Front;
struct QNode * Rear;
};
typedef struct HeaderQNode * Queue;
LGraph CreateGraph(int VertexNum){
LGraph graph=(LGraph)malloc(sizeof(struct GNode));
Vertex V;
graph->Nv=VertexNum;
graph->Ne=0;
for(V=0;V<VertexNum;V++){
graph->G[V].FirstEdge=NULL;
}
return graph;
}
void InsertEdge(LGraph graph,Edge E){
//插入边<V1,V2>
PtrToAdjaVNode NewNode=(PtrToAdjaVNode)malloc(sizeof(struct AdjaVNode));
NewNode->Next = graph->G[E->V1].FirstEdge;
graph->G[E->V1].FirstEdge=NewNode;
NewNode->AdjaV=E->V2;
NewNode->Weight=E->Weight;
}
LGraph ReadBuildGraph(){
//输入格式为顶点 边数\n然后每行:起点 终点 权重
int VertexNum,i;
scanf("%d",&VertexNum);
LGraph graph=CreateGraph(VertexNum);
scanf("%d",&graph->Ne);
if(graph->Ne){
Edge E=(Edge)malloc(sizeof(struct ENode));
for(i=0;i<graph->Ne;i++){
scanf("%d %d %d",&E->V1,&E->V2,&E->Weight);
InsertEdge(graph,E);
}
}
return graph;
}
//以下为队列
struct HeaderQNode * CreateQueue(void)
{
struct HeaderQNode * p;
p=(struct HeaderQNode *)malloc(sizeof(struct HeaderQNode));
p->Front=NULL;p->Rear=NULL;
return p;
}
bool IsEmpty(struct HeaderQNode * p)
{
if(p->Rear==NULL) return true;
else return false;
}
void EnQueue(struct HeaderQNode * p,ElementType V)
{
struct QNode * temp=(struct QNode *)malloc(sizeof(struct QNode));temp->Element=V;
if(p->Rear==NULL){
p->Front=temp;
temp->Next=NULL;
p->Rear=temp;
}else {
p->Rear->Next=temp;
temp->Next=NULL;
p->Rear=temp;
}
}
ElementType DeQueue(struct HeaderQNode * p)
{
ElementType ret;
if(!IsEmpty(p)){
struct QNode * temp=p->Front;
ret=temp->Element;
p->Front=temp->Next;
if(p->Front==NULL) p->Rear=NULL;
free(temp);
}else return 0;
return ret;
}//队列定义结束
int TopSort( LGraph Graph, int Earliest[] )
{ /* 对Graph进行拓扑 */
int Indegree[MaxVertexNum], cnt ;
//int Max[MaxVertexNum]={0};
Vertex V;
PtrToAdjaVNode W;
Queue Q = CreateQueue();
/* 初始化Indegree[] */
for (V=0; V<Graph->Nv; V++){
Indegree[V] = 0;
}
/* 遍历图,得到Indegree[] */
for (V=0; V<Graph->Nv; V++)
for (W=Graph->G[V].FirstEdge; W; W=W->Next)
Indegree[W->AdjaV]++; /* 对有向边<V, W->AdjV>累计终点的入度 */
/* 将所有入度为0的顶点入列 */
for (V=0; V<Graph->Nv; V++)
if ( Indegree[V]==0 )
EnQueue(Q, V);
/* 下面进入拓扑排序 */
cnt = 0;
while( !IsEmpty(Q) ){
V = DeQueue(Q); /* 弹出一个入度为0的顶点 */
cnt++;
/* 对V的每个邻接点W->AdjaV */
for ( W=Graph->G[V].FirstEdge; W; W=W->Next ){
if(Earliest[V]+W->Weight>Earliest[W->AdjaV]){
Earliest[W->AdjaV]=Earliest[V]+W->Weight;
//Max[W->AdjaV]=Earliest[W->AdjaV];
}
if ( --Indegree[W->AdjaV] == 0 )/* 若删除V使得W->AdjV入度为0 */
EnQueue(Q, W->AdjaV); /* 则该顶点入列 */
}
} /* while结束*/
int result=0;
if ( cnt != Graph->Nv )
return 0; /* 说明图中有回路, 返回不成功标志 */
else{
//注意多个终点的情况
for(V=0;V<Graph->Nv;V++){
if(Earliest[V]>result)
result=Earliest[V];
}
}
return result;
}
int main()
{
int answer;
LGraph graph=ReadBuildGraph();
int Earliest[MaxVertexNum]={0};
answer=TopSort(graph,Earliest);
if(answer)
printf("%d",answer);
else printf("Impossible");
return 0;
}