现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
输入格式:
输入数据包括城镇数目正整数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
要想理解普里姆算法,首先要理解图的创建相关知识。
接下来,
结构类型定义Edge,函数 InitEdge()、GetMinEdge()、Prim()三个函数实现普里姆算法得到最小生成树。
完整代码:
#include <iostream>
#include <stdlib.h>
#include <queue>
using namespace std;
#define INFINITY 32767
typedef struct
{
int *vexs; //顶点表
int **arc; //邻接矩阵,可看作边表
int numVertexes,numEdges; //图中当前的顶点数和边数
}MGraph;
typedef struct
{
int vex; //记录最小边的起始节点
int weight; //记录最小边,也就是最小权值
}Edge;
Edge* InitEdge(MGraph *G,int index)
{
Edge* edge = (Edge*)malloc(sizeof(Edge)*G->numVertexes);
for(int i=0;i<G->numVertexes;i++)
{
edge[i].vex=G->vexs[index];
edge[i].weight=G->arc[index][i];
}
return edge;
}
int GetMinEdge(MGraph *G,Edge *edge)
{
int index;
int min=INFINITY;
for(int i=0;i<G->numVertexes;i++)
{
if(edge[i].weight != 0 && min>edge[i].weight)
{
min = edge[i].weight;
index = i;
}
}
return index;
}
void Prim(MGraph *G,int index)
{
int min,sum=0;
Edge *edge = InitEdge(G,index);
for(int i=0;i<G->numVertexes - 1;i++)
{
min = GetMinEdge(G,edge);
//printf("v%d --> v%d, weight = %d\n", edge[min].vex, G -> vexs[min], edge[min].weight);
sum+=edge[min].weight;
edge[min].weight=0;
for(int j=0;j<G->numVertexes;j++)
{
if(G->arc[min][j] < edge[j].weight)
{
edge[j].vex = G->vexs[min];
edge[j].weight = G->arc[min][j];
}
}
}
cout<<sum;
}
MGraph* InitGraph(int numVer,int numEdge)
{
MGraph *G;
G = (MGraph*)malloc(sizeof(MGraph));
G->vexs = (int*)malloc(sizeof(int)*numVer);
G->arc = (int**)malloc(sizeof(int*)*numVer);
for(int i=0;i<numVer;i++)
{
G->vexs[i]=i+1; //城镇从1开始编号
G->arc[i] = (int*)malloc(sizeof(int)*numVer);
for(int j=0;j<numVer;j++)
{
G->arc[i][j] = 0;
}
}
G->numVertexes = numVer;
G->numEdges = numEdge;
return G;
}
int main()
{
MGraph *G;
int N,M;
cin>>N>>M;
G = InitGraph(N,M);
for(int i=0;i<M;i++)
{
int x,y,weight;
cin>>x>>y>>weight;
G->arc[x-1][y-1] = weight;
G->arc[y-1][x-1] = weight;
}
Prim(G,0);
return 0;
}