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
我的答案
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 5 #define ERROR -1 6 #define false 0 7 #define true 1 8 #define MaxVertexNum 100 9 #define INFINITY 65535 10 #define MaxQueue 100 11 typedef int Vertex; 12 typedef int WeightType; 13 typedef int bool; 14 15 //边 16 typedef struct ENode *PtrToENode; 17 struct ENode { 18 Vertex V1, V2; 19 WeightType Weight; 20 }; 21 typedef PtrToENode Edge; 22 23 //邻接点 24 typedef struct AdjVNode *PtrToAdjVNode; 25 struct AdjVNode { 26 Vertex AdjV; //下标 27 WeightType Weight; //边权重 28 PtrToAdjVNode Next; //指向下一个邻接点 29 }; 30 31 //顶点 32 typedef struct VNode { 33 PtrToAdjVNode FirstEdge; //边表头指针 34 // DataType Data; //存顶点的户数据 35 }AdjList[MaxVertexNum]; 36 37 //图结点 38 typedef struct GNode *PtrToGNode; 39 struct GNode { 40 int Nv; 41 int Ne; 42 AdjList G; 43 }; 44 typedef PtrToGNode LGraph; 45 46 struct QNode { 47 Vertex Data[MaxQueue]; 48 int rear; 49 int front; 50 }; 51 typedef struct QNode *Queue; 52 53 int IsEmptyQ(Queue PtrQ) 54 { 55 return (PtrQ->front == PtrQ->rear); 56 } 57 58 void AddQ(Queue PtrQ, Vertex item) 59 { 60 if((PtrQ->rear+1)%MaxQueue == PtrQ->front) { 61 printf("Queue full"); 62 return; 63 } 64 PtrQ->rear = (PtrQ->rear+1)%MaxQueue; 65 PtrQ->Data[PtrQ->rear] = item; 66 } 67 68 Vertex DeleteQ(Queue PtrQ) 69 { 70 if(PtrQ->front == PtrQ->rear) { 71 printf("Queue Empty"); 72 return -1; 73 } else { 74 PtrQ->front = (PtrQ->front+1)%MaxQueue; 75 return PtrQ->Data[PtrQ->front]; 76 } 77 } 78 79 LGraph CreateGraph(int VertexNum) 80 { 81 Vertex V; 82 LGraph Graph; 83 84 Graph = (LGraph)malloc(sizeof(struct GNode)); 85 Graph->Nv = VertexNum; 86 Graph->Ne = 0; 87 88 for(V=0;V<Graph->Nv;V++) 89 Graph->G[V].FirstEdge = NULL; 90 91 return Graph; 92 } 93 94 void InsertEdge(LGraph Graph, Edge E) 95 { 96 PtrToAdjVNode NewNode; 97 98 //有向边 99 NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode)); 100 NewNode->AdjV = E->V2; 101 NewNode->Weight = E->Weight; 102 //向V1插入V2 103 NewNode->Next = Graph->G[E->V1].FirstEdge; 104 Graph->G[E->V1].FirstEdge = NewNode; 105 } 106 107 LGraph BuildGraph() 108 { 109 LGraph Graph; 110 Edge E; 111 int Nv, i; 112 113 scanf("%d", &Nv); 114 Graph = CreateGraph(Nv); 115 116 scanf(" %d\n", &(Graph->Ne)); 117 if(Graph->Ne != 0) { 118 E = (Edge)malloc(sizeof(struct ENode)); 119 for(i=0;i<Graph->Ne;i++) { 120 scanf("%d %d %d\n", &E->V1, &E->V2, &E->Weight); 121 InsertEdge(Graph, E); 122 } 123 } 124 125 return Graph; 126 } 127 128 void PrintGraph(LGraph Graph) 129 { 130 Vertex V; 131 PtrToAdjVNode W; 132 for(V=0;V<Graph->Nv;V++) { 133 printf("%d:", V); 134 for(W=Graph->G[V].FirstEdge;W;W=W->Next) { 135 printf("[%3d %3d] ", W->AdjV, W->Weight); 136 } 137 printf("\n"); 138 } 139 } 140 141 142 143 /* 邻接表存储 - 拓扑排序算法 */ 144 bool TopSort( LGraph Graph, Vertex TopOrder[], Vertex Earliest[]) 145 { /* 对Graph进行拓扑排序, TopOrder[]顺序存储排序后的顶点下标 */ 146 int Indegree[MaxVertexNum], cnt; 147 Vertex V; 148 PtrToAdjVNode W; 149 150 Queue Q = (Queue)malloc(sizeof(struct QNode)*( Graph->Nv )); 151 152 /* 初始化Indegree[] */ 153 for (V=0; V<Graph->Nv; V++) 154 Indegree[V] = 0; 155 156 /* 遍历图,得到Indegree[] */ 157 for (V=0; V<Graph->Nv; V++) 158 for (W=Graph->G[V].FirstEdge; W; W=W->Next) 159 Indegree[W->AdjV]++; /* 对有向边<V, W->AdjV>累计终点的入度 */ 160 161 /* 将所有入度为0的顶点入列 */ 162 for (V=0; V<Graph->Nv; V++) 163 if ( Indegree[V]==0 ) { 164 AddQ(Q, V); 165 Earliest[V] = 0; //起点为0 166 } 167 168 /* 下面进入拓扑排序 */ 169 cnt = 0; 170 while( !IsEmptyQ(Q) ){ 171 V = DeleteQ(Q); /* 弹出一个入度为0的顶点 */ 172 TopOrder[cnt++] = V; /* 将之存为结果序列的下一个元素 */ 173 /* 对V的每个邻接点W->AdjV */ 174 for ( W=Graph->G[V].FirstEdge; W; W=W->Next ) 175 if ( --Indegree[W->AdjV] == 0 ) {/* 若删除V使得W->AdjV入度为0 */ 176 AddQ(Q, W->AdjV); /* 则该顶点入列 */ 177 Earliest[W->AdjV] = Earliest[V] + W->Weight; 178 // if((Earliest[V]+W->Weight)>Earliest[W->AdjV] && Earliest[W->AdjV]) 179 // Earliest[W->AdjV] = Earliest[V] + W->Weight; 180 } 181 } /* while结束*/ 182 183 if ( cnt != Graph->Nv ) 184 return false; /* 说明图中有回路, 返回不成功标志 */ 185 else 186 return true; 187 } 188 189 int main() 190 { 191 LGraph Graph; 192 WeightType Earliest[MaxVertexNum]; 193 Vertex TopOrder[MaxVertexNum],V; 194 int ret; 195 196 Graph = BuildGraph(); 197 // PrintGraph(Graph); 198 ret = TopSort(Graph, TopOrder, Earliest); 199 if(ret == false) { 200 printf("Impossible"); 201 } else if(ret == true) { 202 int max = Earliest[0]; 203 for(int i=0;i<Graph->Nv;i++) { 204 // printf("%d: [%d]\n", i, Earliest[i]); 205 if(max < Earliest[i]) 206 max = Earliest[i]; 207 } 208 printf("%d", max); 209 } 210 // printf("TopOrder:"); 211 // for(V=0;V<Graph->Nv;V++) 212 // printf("%d ", TopOrder[V]); 213 // printf("\n"); 214 return 0; 215 }