MST(Minimum Spanning Tree,最小生成树)
经典运用城市铺路问题
通常有最小生成树有Prim和Kruskal两种算法
这边先介绍Prim算法
时间复杂度是O(n^2)
牛客上有道选择题答案说是O(n+e)我是不太明白
Prim算法是从点的角度出发
所以两者相比较Prim算法适合于解决边稠密的网
具体流程:
初始化:
图中所有顶点集合为G
加入MST的点集合为V
任取一点a开始,加入V中
步骤
1) 找集合G - V中的点b,与V中某点a最小的权值
2) 将这点加入V中,b与a相连就构成一条边
3)返回到第一步,直到所有顶点都加入V中,就得到一颗MST
下面是模拟过程
这里测试数据与上图无关
Sample Input
9 15
0 1 10
0 5 11
1 2 18
1 6 16
2 3 22
2 8 8
3 4 20
3 7 16
3 6 24
3 8 21
4 5 26
4 7 7
5 6 17
6 7 19
1 8 12
Sample Output
0 1
0 5
1 8
8 2
1 6
6 7
7 4
7 3
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXEDGE = 20;
const int MAXVEX = 20;
const int INIFINITY = 100000;
//封装顶点,边,数组顶点到顶点间的权值
typedef struct{
int arc[MAXVEX][MAXVEX];
int numVertexes, numEdges;
}MGraph;
MGraph G;
void CreateMGraph(MGraph *G);
void MiniSpanTree_Prim(MGraph G);
int main(int argc, const char * argv[])
{
CreateMGraph(&G);
MiniSpanTree_Prim(G);
return 0;
}
void CreateMGraph(MGraph *G)
{
cin >> G->numVertexes >> G->numEdges;
//初始化
for(int i = 0; i < G->numVertexes; i++)
for(int j = 0; j < G->numVertexes; j++)
//顶点自身到自身无权值,不连通的顶点间取无穷大
if(i == j)
G->arc[i][j] == 0;
else
G->arc[i][j] = G->arc[j][i] = INIFINITY;
//构造连通图
for(int i = 0; i < G->numEdges; i++)
{
int v1,v2,w;
scanf("%d %d %d", &v1, &v2, &w);
G->arc[v1][v2] = w;
}
//利用连通的对称性
for(int i = 0; i < G->numVertexes; i++)
for(int j = 0; j < G->numVertexes; j++)
G->arc[j][i] = G->arc[i][j];
}
//Prim算法生成最小生成树
void MiniSpanTree_Prim(MGraph G)
{
int adjvex[MAXVEX] = {0, }; //adjvex[i] 当下已生成的树中到i权值最小的顶点
int lowcost[MAXVEX] = {0, }; //lowcost[i] 对应i到adjvex[i]两顶点中的权值
lowcost[0] = 0; //赋值为0表示已加入生成树中
for(int i = 1; i < G.numVertexes; i++){
lowcost[i] = G.arc[0][i]; //0与各顶点的权值存入
adjvex[i] = 0; //初始化目前全是与顶点0相接
}
for(int i = 1; i < G.numVertexes; i++)
{
int min = INIFINITY;
int k = 0; //初始化最小值
//循环所有顶点,找出最小权值,把顶点赋给k
for(int j = 1; j < G.numVertexes; j++)
if(lowcost[j] != 0 && lowcost[j] < min){
min = lowcost[j];
k = j;
}
printf("%d %d\n", adjvex[k], k);
lowcost[k] = 0; //标记该顶点已完成任务
//重新寻找从刚加入的顶点到各顶点的权值是否比原先的adjvex[j]到j的权值更小
for(int j = 1; j < G.numVertexes; j++)
if(lowcost[j] != 0 && G.arc[k][j] < lowcost[j]){
adjvex[j] = k;
lowcost[j] = G.arc[k][j];
}
}
}
650