一、前导
1. 需要掌握的知识
- 最小生成树,Prim算法
2. 题目信息
- 题目来源:PTA / 拼题A
- 题目地址:公路村村通
二、解题思路分析
1. 题意理解
- 最小生成树问题
1. 1 输入数据
6 15
1 2 5
1 3 3
4 5 10
4 6 8
5 6 3
1.2 输出数据
- 输出公路村村通需要的最低成本,即打印最小生成树的权重;若不存在MST,打印-1
2. 思路分析(重点)
- 最小生成树问题,可以用Prim算法解决,由于题目仅要求输出最小生成树的权重,并未要求打印最小生成树,对Prim算法进行适当调整即可AC
三、具体实现
1. 弯路和bug
- 按照Prim算法(避环法)实现即可
2. 代码框架(重点)
2.1 采用的数据结构
- 使用二维数组存储图:使用空间换解题时间,代码量会少很多
#define max 1001
int Graph[max][max];
int VertexNumber,EdgeNumber;
- 数组dist 和 parent配合Prim算法使用
int dist[max];
int parent[max];
2.2 程序主体框架
程序伪码描述
int main()
{
1.构建图
2.执行Prim算法
return 0;
}
2.3 各分支函数
- FindDistMin( ):找到dist数组中的最小值 且 该顶点未被收录到MST中
#define Null -1
#define maxWeight 99999
typedef int vertex;
vertex FindDistMin()
{
vertex V=Null;
int distMin=maxWeight;
for(int i=1;i<=VertexNumber;i++)
{
if(dist[i] && distMin>dist[i])
{
distMin=dist[i];
V=i;
}
}
return V;
}
- Prim() :本题AC的核心函数。首先复习下Prim算法的步骤,由于本题仅需要计算MST的权值,因此不涉及MST的创建(包括边的插入),因此只需要使用Prim算法中的非边部分就可以AC本题
void Prim()
{
vertex V,W;
int vertexCount=0;
int MSTWeight=0;
for(V=1;V<=VertexNumber;V++)
{
parent[V]=Source;
dist[V]=maxWeight;
}
dist[Source]=0;
vertexCount++;
parent[Source]=-1;
for(V=1;V<=VertexNumber;V++)
{
if(Graph[Source][V])
dist[V]=Graph[Source][V];
}
while(true)
{
V=FindDistMin();
if(V==Null) break;
dist[V]=0;
vertexCount++;
MSTWeight += Graph[parent[V]][V];
for(W=1;W<=VertexNumber;W++)
{
if(dist[W]!=0 && Graph[V][W]!=0)
{
if(Graph[V][W]<dist[W])
{
dist[W]=Graph[V][W];
parent[W]=V;
}
}
}
}
if(vertexCount!=VertexNumber)
cout<<Null;
else cout<<MSTWeight;
return;
}
3. 完整编码
- 本文如果对你有帮助,请点赞鼓励 ,谢谢 😊
- 如有建议或意见,欢迎留言
#include <cstdlib>
#include <iostream>
using namespace std;
#define max 1001
#define Null -1
#define maxWeight 99999
#define Source 1
typedef int vertex;
int Graph[max][max];
int VertexNumber,EdgeNumber;
int dist[max];
int parent[max];
void createGraph();
void Prim();
vertex FindDistMin();
int main()
{
createGraph();
Prim();
return 0;
}
void Prim()
{
vertex V,W;
int vertexCount=0;
int MSTWeight=0;
for(V=1;V<=VertexNumber;V++)
{
parent[V]=Source;
dist[V]=maxWeight;
}
dist[Source]=0;
vertexCount++;
parent[Source]=-1;
for(V=1;V<=VertexNumber;V++)
{
if(Graph[Source][V])
dist[V]=Graph[Source][V];
}
while(true)
{
V=FindDistMin();
if(V==Null) break;
dist[V]=0;
vertexCount++;
MSTWeight += Graph[parent[V]][V];
for(W=1;W<=VertexNumber;W++)
{
if(dist[W]!=0 && Graph[V][W]!=0)
{
if(Graph[V][W]<dist[W])
{
dist[W]=Graph[V][W];
parent[W]=V;
}
}
}
}
if(vertexCount!=VertexNumber)
cout<<Null;
else cout<<MSTWeight;
return;
}
vertex FindDistMin()
{
vertex V=Null;
int distMin=maxWeight;
for(int i=1;i<=VertexNumber;i++)
{
if(dist[i] && distMin>dist[i])
{
distMin=dist[i];
V=i;
}
}
return V;
}
void createGraph()
{
vertex V1,V2,Weight;
cin>>VertexNumber>>EdgeNumber;
for(int i=1;i<=VertexNumber;i++)
{
for(int j=1;j<=VertexNumber;j++)
{
Graph[i][j]=0;
}
}
for(int k=1;k<=EdgeNumber;k++)
{
cin>>V1>>V2>>Weight;
Graph[V1][V2]=Weight;
Graph[V2][V1]=Weight;
}
return;
}
四、参考
- 浙江大学 陈越、何钦铭老师主讲的数据结构