08-图7 公路村村通(30 分)Prim

现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。

输入格式:

输入数据包括城镇数目正整数N(1000)和候选道路数目M(3N);随后的M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到N编号。

输出格式:

输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出1,表示需要建设更多公路。

输入样例:

6 15
1 2 5
1 3 3
1 4 7
1 5 4
1 6 2
2 3 4
2 4 6
2 5 2
2 6 6
3 4 6
3 5 1
3 6 1
4 5 10
4 6 8
5 6 3

输出样例:

12

我的答案
  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 10000
  9 #define INFINITY     65535
 10 typedef int Vertex;
 11 typedef int WeightType;
 12 typedef int bool;
 13 
 14 //
 15 typedef struct ENode *PtrToENode;
 16 struct ENode {
 17     Vertex V1, V2;
 18     WeightType Weight;
 19 };
 20 typedef PtrToENode Edge;
 21 
 22 //邻接矩阵
 23 typedef struct GNode *PtrToGNode;
 24 struct GNode {
 25     int Nv;
 26     int Ne;
 27     WeightType G[MaxVertexNum][MaxVertexNum];
 28 };
 29 typedef PtrToGNode MGraph;
 30 
 31 //邻接点
 32 typedef struct AdjVNode *PtrToAdjVNode;
 33 struct AdjVNode {
 34     Vertex AdjV;
 35     WeightType Weight;
 36     PtrToAdjVNode Next;
 37 };
 38 
 39 typedef struct VNode {
 40     PtrToAdjVNode FirstEdge;
 41     // DataType Data;
 42 }AdjList[MaxVertexNum];
 43 
 44 typedef struct LNode *PtrToLNode;
 45 struct LNode {
 46     int Nv;
 47     int Ne;
 48     AdjList G;
 49 };
 50 typedef PtrToLNode LGraph;
 51 
 52 //邻接矩阵
 53 MGraph MGraphCreate(int VertexNum)
 54 {
 55     Vertex V, W;
 56     MGraph Graph;
 57 
 58     Graph = (MGraph)malloc(sizeof(struct GNode));
 59     Graph->Nv = VertexNum;
 60     Graph->Ne = 0;
 61 
 62     for(V=0;V<Graph->Nv;V++) {
 63         for(W=0;W<Graph->Nv;W++) {
 64             Graph->G[V][W] = INFINITY;
 65         }
 66     }
 67 
 68     return Graph;
 69 }
 70 
 71 void MGraphInsertEdge(MGraph Graph, Edge E)
 72 {
 73     Graph->G[E->V1][E->V2] = E->Weight;
 74     Graph->G[E->V2][E->V1] = E->Weight;
 75 }
 76 
 77 MGraph MGraphBuild()
 78 {
 79     MGraph Graph;
 80     Edge E;
 81     int i, Nv;
 82 
 83     scanf("%d ", &Nv);
 84     Graph = MGraphCreate(Nv);
 85 
 86     scanf("%d
", &(Graph->Ne));
 87     if(Graph->Ne != 0) {
 88         E = (Edge)malloc(sizeof(struct ENode));
 89         for(i=0;i<Graph->Ne;i++) {
 90             scanf("%d %d %d
", &E->V1, &E->V2, &E->Weight);
 91             E->V1--;
 92             E->V2--;
 93             MGraphInsertEdge(Graph, E);
 94         }
 95     }
 96 
 97     return Graph;
 98 }
 99 
100 void MGraphPrint(MGraph Graph)
101 {
102     Vertex V, W;
103     printf("Graph:
");
104     for(V=0;V<Graph->Nv;V++) {
105         for(W=0;W<Graph->Nv;W++) 
106             printf("[%5d]	" , Graph->G[V][W]);
107         printf("
");
108     }
109     printf("-----------------------
");
110 }
111 
112 //邻接表
113 LGraph LGraphCreate(int VertexNum)
114 {
115     Vertex V;
116     LGraph Graph;
117 
118     Graph = (LGraph)malloc(sizeof(struct LNode));
119     Graph->Nv = VertexNum;
120     Graph->Ne = 0;
121     for(V=0;V<Graph->Nv;V++)
122         Graph->G[V].FirstEdge = NULL;
123 
124     return Graph;
125 }
126 
127 void LGraphInsertEdge(LGraph Graph, Edge E)
128 {
129     PtrToAdjVNode NewNode;
130 
131     NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
132     NewNode->AdjV = E->V2;
133     NewNode->Weight = E->Weight;
134 
135     NewNode->Next = Graph->G[E->V1].FirstEdge;
136     Graph->G[E->V1].FirstEdge = NewNode;
137 
138     NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
139     NewNode->AdjV = E->V1;
140     NewNode->Weight = E->Weight;
141 
142     NewNode->Next = Graph->G[E->V2].FirstEdge;
143     Graph->G[E->V2].FirstEdge = NewNode;
144 }
145 
146 LGraph LGraphBuilGraph()
147 {
148     LGraph Graph;
149     Edge E;
150     // Vertex V;
151     int Nv, i;
152 
153     scanf("%d", &Nv);
154     Graph = LGraphCreate(Nv);
155 
156     scanf("%d", &(Graph->Ne));
157     if(Graph->Ne != 0) {
158         E = (Edge)malloc(sizeof(struct ENode));
159         for(i=0;i<Graph->Ne;i++) {
160             scanf("%d %d %d", &E->V1, &E->V2, &E->Weight);
161             LGraphInsertEdge(Graph, E);
162         }
163     }
164 
165     return Graph;
166 }
167 
168 Vertex FindMinDist(MGraph Graph, WeightType dist[])
169 {
170     Vertex MinV, V;
171     WeightType MinDist = INFINITY;
172 
173     for(V=0;V<Graph->Nv;V++) {
174         if(dist[V] != 0 && dist[V] < MinDist) {
175             MinDist = dist[V];
176             MinV = V;
177         }
178     }
179     if(MinDist < INFINITY)
180         return MinV;
181     else return ERROR;
182 }
183 
184 int Prim(MGraph Graph, LGraph MST)
185 {   /* 将最小生成树保存为邻接表存储的图MST,返回最小权重和 */
186     WeightType dist[MaxVertexNum], TotalWeight;
187     Vertex parent[MaxVertexNum], V, W;
188     int VCount;
189     Edge E;
190 
191     /* 初始化,默认初始点下标是0 */
192     for(V=0;V<Graph->Nv;V++) {
193     /* 这里假设若V到W没有直接的边,则Graph->G[V][W]定义为INIFINITY */
194         dist[V] = Graph->G[0][V];
195         parent[V] = 0;  /* 暂且定义所有顶点的父结点都是初始点0 */
196     }
197     TotalWeight = 0;    /* 初始化权重和 */
198     VCount = 0;         /* 初始化收录的顶点数 */
199     /* 创建包含所有顶点但没有边的图。注意用邻接表版本 */
200     MST = LGraphCreate(Graph->Nv);
201     E = (Edge)malloc(sizeof(struct ENode));
202 
203     /* 将初始点0收录进MST */
204     dist[0] = 0;
205     VCount++;
206     parent[0] = -1;     /* 当前树根是0 */
207 
208     while(1) {
209         V = FindMinDist(Graph, dist);
210         /* V = 未被收录顶点中dist最小者 */
211         if(V == ERROR)      /* 若这样的V不存在 */
212             break;          /* 算法结束 */
213 
214         /* 将V及相应的边<parent[V], V>收录进MST */
215         E->V1 = parent[V];
216         E->V2 = V;
217         E->Weight = dist[V];
218         LGraphInsertEdge(MST, E);
219         TotalWeight += dist[V];
220         dist[V] = 0;
221         VCount++;
222 
223         for(W=0;W<Graph->Nv;W++) {  /* 对图中的每个顶点W */
224             if(dist[W]!=0 && Graph->G[V][W]<INFINITY) {
225             /* 若W是V的邻接点并且未被收录 */
226                 if(Graph->G[V][W] < dist[W]) {
227                 /* 若收录V使得dist[W]变小 */
228                     dist[W] = Graph->G[V][W];   /* 更新dist[W] */
229                     parent[W] = V;              /* 更新树 */
230                 }
231             }
232         }
233     }
234     if(VCount < Graph->Nv)      /* MST中收的顶点不到|V|个 */
235         TotalWeight = ERROR;
236     return TotalWeight;         /* 算法执行完毕,返回最小权重和或错误标记 */
237 }
238 
239 int main()
240 {
241     MGraph Graph;
242     LGraph Lraph;
243     WeightType minCost;
244     Graph = MGraphBuild();
245     // MGraphPrint(Graph);
246     minCost = Prim(Graph, Lraph);
247     printf("%d
", minCost);
248     return 0;
249 }
无欲速,无见小利。欲速,则不达;见小利,则大事不成。
原文地址:https://www.cnblogs.com/ch122633/p/9003870.html