08-图7 公路村村通(30 分)Prim
Posted 思而不学
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n", &(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\n", &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:\n"); 104 for(V=0;V<Graph->Nv;V++) { 105 for(W=0;W<Graph->Nv;W++) 106 printf("[%5d]\t" , Graph->G[V][W]); 107 printf("\n"); 108 } 109 printf("-----------------------\n"); 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\n", minCost); 248 return 0; 249 }
以上是关于08-图7 公路村村通(30 分)Prim的主要内容,如果未能解决你的问题,请参考以下文章