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

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
", &(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
", &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("
");
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]
", 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("
");
214     return 0;
215 }
无欲速,无见小利。欲速,则不达;见小利,则大事不成。
原文地址:https://www.cnblogs.com/ch122633/p/9007751.html