08-图7 公路村村通 (30 分)
前言:本题来自浙大PTA上的数据结构练习题
题目描述
现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
输入格式:
输入数据包括城镇数目正整数N (≤1000)和候选道路数目M (≤3N );随后的M 行对应M 条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到N 编号。
输出格式:
输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路。
输入样例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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结尾无空行
输出样例:
题目理解与思路
本题是最小生成树的问题,可以采用Kruskal算法加并查集实现,或者使用简单的Prim算法实现。
本文使用Kruskal算法来解题,代码如下
Kruskal
本解法越写越复杂,而且由于博主今日不在状态,写不动了,还没有通过测试,等待后续完善
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 #include <stdio.h> #include <stdlib.h> #define MaxVer 1005 #define Inf 65535 typedef struct GNode * PtrToGNode ;struct GNode { int V; int E; int G[MaxVer][MaxVer]; }; typedef PtrToGNode MGraph;int collected[MaxVer] = {0 };int S[MaxVer];int VisitedE[MaxVer][MaxVer] = {0 };MGraph creatGraph (int V,int E) { int i,V1,V2,D,j; MGraph Graph; Graph = (MGraph)malloc (sizeof (struct GNode)); Graph->V = V; Graph->E = E; for (i = 0 ;i < V;i++) for (j = 0 ;j < V;j++) { if (i == j) { Graph->G[i][j] = 0 ; S[i] = -1 ; } else Graph->G[i][j] = Inf; } for (i = 0 ;i < Graph->E;i++) { scanf ("%d %d %d\n" ,&V1,&V2,&D); Graph->G[V1-1 ][V2-1 ] = Graph->G[V2-1 ][V1-1 ] = D; } return Graph; } int findRoot (int V) { if (S[V] < 0 ) return V; else return S[V] = findRoot(S[V]); } void Union (int Root1,int Root2) { if (S[Root1] < S[Root2]) { S[Root1] += S[Root2]; S[Root2] = Root1; } else { S[Root2] += S[Root1]; S[Root1] = Root2; } } void Kruskal (MGraph Graph) { int MinEdge,sum; int V1,V2,p1,p2; int i,j; sum = 0 ; int num = Graph->V; while (num > 1 ) { MinEdge = Inf; for (i=0 ;i<Graph->E;i++) { for (j=i;j<Graph->E;j++) { if ((Graph->G[i][j] < MinEdge)&&(VisitedE[i][j] == 0 )) { MinEdge = Graph->G[i][j]; V1 = i,V2 = j; } } } if (MinEdge == Inf)break ; VisitedE[V1][V2] = 1 ; VisitedE[V2][V1] = 1 ; p1 = findRoot(V1); p2 = findRoot(V2); if (p1 != p2){ sum += MinEdge; num--; Union(V1,V2); } } if (num > 1 ) { printf ("-1\n" ); return ; } printf ("%d\n" ,sum); } int main () { int V,E; scanf ("%d %d\n" ,&V,&E); MGraph Graph; Graph = creatGraph(V,E); Kruskal(Graph); return 0 ; }
后记
今日体重
今天的体重是脱了鞋称的,所以比昨天轻很多2333