最小生成树
最小生成树的概念:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。 [1] 最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。(来自百度百科)
- 普利姆算法(Prim)
- 朴素Prim O(n^2) 适用于稠密图
- 堆优化版Prim O(mlogn) 适用于稀疏图
- 克鲁斯卡尔算法(Kruskal) O(mlongm) 适用于稀疏图
朴素Prim算法
- 算法思路:
首先将所有点的权值初始化为正无穷,将第一个点先放进集合中(集合指当前的生成树),经过n次迭代,找到不在集合当中的最短距离的点,用t代替,并把他加入集合,之后用t更新其他点到集合的距离,即st[t]=true
。
核心代码:
int prim()
{
memset(dist, 0x3f,sizeof dist);
int res=0;
for(int i=0;i<n;i++)
{
int t=-1;
for(int j=1;j<=n;j++)
if(!st[j]&&(t==-1||dist[t]>dist[j]))
t=j;
if(i&&dist[t]==INF) return INF;
if(i>1) res+=dist[t];
for(int j=1;j<=n;j++) dist[j]=min(dist[j],g[t][j]);
st[t]=true;
}
return res;
}
例题:
原题链接 : https://www.acwing.com/problem/content/description/1141/
学校有 n 台计算机,编号是 1∼n,为了方便数据传输,现要将它们用数据线连接起来,同一条数据线中数据的传输可以是 双向 的。
两台计算机被连接是指它们有数据线连接。
由于计算机所处的位置不同,因此不同的两台计算机的连接费用往往是不同的。
当然,如果将任意两台计算机都用数据线连接,费用将是相当庞大的。
为了节省费用,我们采用数据的间接传输手段,即一台计算机可以间接的通过若干台计算机(作为中转)来实现与另一台计算机的连接。
现在由你负责连接这些计算机,任务是使任意两台计算机都连通(不管是直接的或间接的)。
输入格式
第一行为整数 n,表示计算机的数目。
此后的 n 行,每行 n 个整数,输入一个对角线上全部是0的 对称矩阵。
其中第 x+1 行 y 列的整数表示直接连接第 x 台计算机和第 y 台计算机的费用。
输出格式
一个整数,表示最小的连接费用。
数据范围
2≤n≤100,
连接任意两台计算机的费用均是非负整数且不超过10000。
输入样例:
3
0 1 2
1 0 1
2 1 0
输出样例:
2
C++代码:
#include