7-1 公路村村通 (30 分)
现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
输入格式:
输入数据包括城镇数目正整数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
邻接矩阵表示方法
#include <stdio.h>
#include <stdlib.h>
#define MaxVertexNum 1005 /* 最大顶点数设为1005*/
#define INFINITY 65535 /* ∞设为双字节无符号整数的最大值65535*/
typedef int Vertex; /*用顶点下标表示顶点,为整型*/
typedef int WeightType; /* 边的权值设为整型 */
typedef char DataType; /* 顶点存储的数据类型设为字符型 */
typedef struct GNode *PtrToGNode;
struct GNode{
DataType Data[ MaxVertexNum ]; /* 顶点表 */
WeightType G[ MaxVertexNum ][ MaxVertexNum ]; /* 邻接矩阵,即边表 */
int Nv, Ne;
};
typedef PtrToGNode MGraph; /* MGragh是以邻接矩阵存储的图类型 */
/*边的定义*/
typedef struct ENode *PtrToENode;
struct ENode
{
Vertex V1,V2; /*有向边<V1,V2>*/
WeightType Weight; /*权重*/
};
typedef PtrToENode Edge;
MGraph CreateGraph(int VertexNum)/*初始化一个有VertexNum个顶点但没有边的图*/
{
Vertex V, W;
MGraph Graph;
Graph = (MGraph)malloc(sizeof(struct GNode));
Graph->Nv = VertexNum;
Graph->Ne = 0;
for(V = 0; V < Graph->Nv; V++){
for(W = 0; W < Graph->Nv ; W++){
Graph->G[V][W] = INFINITY;
}
}
return Graph;
}
void InsertEdge(MGraph Graph,Edge E)/*插入边<V1,V2>*/
{
Graph->G[E->V1][E->V2] = E->Weight;
Graph->G[E->V2][E->V1] = E->Weight; /*无向图*/
}
MGraph BuildGraph()/*创建图的邻接矩阵存储结构*/
{
MGraph Graph;
Edge E;
Vertex V, *Visited;
int Nv , i;
scanf("%d", &Nv);
Graph = CreateGraph(Nv);
scanf("%d", &(Graph->Ne));
if(Graph->Ne != 0){
E = (Edge)malloc(sizeof(struct ENode));
for(i = 0; i < Graph->Ne; i++){
scanf("%d%d%d", &E->V1, &E->V2, &E->Weight);
E->V1--; //存数组的时候零下标开始
E->V2--; //存数组的时候零下标开始
InsertEdge(Graph, E);
}
}
return Graph;
}
Vertex FindMin(MGraph Graph,WeightType dist[])
{
Vertex MinV, V;
WeightType MinDist = INFINITY;
for(V = 0; V < Graph->Nv ; V++){
if(dist[V] != 0 && dist[V]<MinDist){
MinDist = dist[V];
MinV = V;
}
}
if(MinDist < INFINITY)return MinV;
else return 0;
}
int Prim(MGraph Graph, MGraph MST)
{
WeightType dist[MaxVertexNum], TotalWeight = 0;
Vertex parent[MaxVertexNum], V, W;
int VCount = 0;
Edge E;
for(V = 0; V < Graph->Nv ; V++){
dist[V] = Graph->G[0][V];
parent[V] = 0;
}
dist[0] = 0;
VCount++;
E = (Edge)malloc(sizeof(struct ENode));
parent[0] = -1;
while(1){
V = FindMin(Graph, dist);
if(V == 0)break;
E->V1 = parent[V];
E->V2 = V;
E->Weight = dist[V];
InsertEdge(MST, E);
TotalWeight = TotalWeight + dist[V];
dist[V] = 0;
VCount++;
for(W = 0; W < Graph->Nv ; W++){
if(dist[W] != 0 && Graph->G[V][W]<INFINITY){
if(Graph->G[V][W] < dist[W]){
dist[W] = Graph->G[V][W];
parent[W] = V;
}
}
}
}
if(VCount < Graph->Nv)TotalWeight = -1;//如果输入数据不足以保证畅通,则输出?1,表示需要建设更多公路
return TotalWeight;
}
int main()
{
MGraph G, MST;
WeightType Sum;
G = BuildGraph();
MST = CreateGraph(G->Nv);
Sum = Prim(G, MST);
printf("%d", Sum);
return 0;
}