具体思路可以看我之前的文章https://blog.csdn.net/qq_38279908/article/details/83473010
我这里就简单说说思路:每次都是取这种边:一边顶点是在树内的顶点,一边顶点是树外的顶点,且权值最小的,加入树中,顶点也改为已探索,之后更新lowcost数组和clostest数组,lowcost数组记录的是目前一直的到各节点的距离,closest数组记录的是各节点的前驱节点,最后还需要一个标记数组flag,用于记录顶点是否探索过,探索过的顶点为false,没有探索过的为true,以此避免循环形成环。
#include<iostream>
#include<vector>
using namespace std;
int InputGraph(vector<vector<int>> &graph)
{
int count = 0;
cin >> count;
for (int i=0;i<count;i++)
{
int start = -1, end = -1, weight = 0;
cin >> start >> end >> weight;
graph[start][end]= graph[end][start] = weight;
}
return count;
}
int prim(vector<vector<int>> &graph, vector<int> &lowcost, vector<int> &closest) //n为边的数量
{
int weight = 0;
int size = graph.size();
vector<bool> flag(size,true);
flag[0] = false;
closest[0] = -1;
cout << "节点添加顺序如下: ";
cout << "0 ";
for (int i = 1; i < size; i++)
{
lowcost[i] = graph[0][i];
closest[i] = 0;
}
for (int i = 0; i < size - 1; i++)
{
int min = 999999, index = -1;
for (int i = 0; i < size; i++)
{
if (min > lowcost[i] && flag[i] == true)
{
index = i;
min = lowcost[i];
}
}
flag[index] = false;
weight += min;
cout << index << " ";
for (int i = 0; i < size; i++)
{
if (lowcost[i] > graph[index][i]&&flag[i]==true)
{
lowcost[i] = graph[index][i];
closest[i] = index;
}
}
}
return weight;
}
int main()
{
int size = 6;
vector<vector<int>> graph(size,vector<int>(size,999999));
vector<int> lowcost(size);
vector<int> closest(size); //保存父节点信息
int n = InputGraph(graph);
cout <<endl<<"weight="<<prim(graph, lowcost, closest) << endl;
system("pause");
return 0;
}
输入:
8
0 1 2
0 2 3
1 3 7
2 3 5
2 4 3
3 4 4
4 5 2
1 5 8
结果如下: