图论算法之Prime(算法) 求最小生成树
{0,7,4,0,0,0}
{7,0,6,2,0,4}
{4,6,0,0,9,8}
{0,2,0,0,0,7}
{0,0,9,0,0,1}
{0,4,8,7,1,0}
、如上的二维数组 ,假设0为不可达点,由此邻接矩阵,可以画出图如下所示
接下来我们模拟下从0出发的最小生成树
先将0标记为已经被访问,并将相邻未访问的节点的最小开销赋值给lowcost[ ]数组
此时最短路径依旧为0,从0->0依旧是0
接下来,从其他未访问的节点中,找到lowcost值最小的,作为下一个访问的点,并将值加入最短路径开销的和中。并标记为已经访问
接下来从 刚刚访问的节点,找到剩下的未访问的节点,到刚刚访问节点的的路径开销,判断与lowcost中值的大小,如果加入最小生成树的路径开销小于lowcost中已经有的,这时修改lowcost的值。接下来继续循环之前的操作。直到所有的点都被访问,结束循环。
#include <iostream>
#include <algorithm>
#include <cstring>
#define INF 0x3f3f3f3f
using namespace std;
const int N = 6;
bool visted[N];
int lowcost[N] = {0};
int map[N][N] = { {INF,7,4,INF,INF,INF},
{7,INF,6,2,INF,4},
{4,6,INF,INF,9,8},
{INF,2,INF,INF,INF,7},
{INF,INF,9,INF,INF,1},
{INF,4,8,7,1,INF}
};
int prime(int cur)
{
int index = cur;
int sum = 0; //最短路径长
int i = 0,j = 0;
memset(visted,false,sizeof(visted));
visted[cur] = true;
cout << cur << "->";
for(int i = 0;i < N;i++){
lowcost[i] = map[cur][i];
}
for(int i = 1; i < N;i++){
int min = INF;
for(int j = 0;j < N;j++){
//找到未被访问的节点,且当前的路径开销最小,加入最小生成树中
if(!visted[j] && lowcost[j]<min){
min = lowcost[j];
index = j;
}
}
visted[index] = true;
cout << index << "->";
sum += min;
//再找未被访问过的,且路径开销大于到当前节点的,更改最小开销为最新的
for(int j = 0;j < N;j++){
if(!visted[j] && lowcost[j]>map[index][j]){
lowcost[j] = map[index][j];
}
}
}
// cout << endl;
return sum;
}
int main()
{
cout << prime(0) << endl;//从0开始
cout << prime(1) << endl;//从1开始
cout << prime(2) << endl;//从2开始
cout << prime(3) << endl;//从3开始
cout << prime(4) << endl;//从4开始
cout << prime(5) << endl;//从5开始
return 0;
}
输出结果:
0->2->1->3->5->4->17
1->3->5->4->2->0->17
2->0->1->3->5->4->17
3->1->5->4->2->0->17
4->5->1->3->2->0->17
5->4->1->3->2->0->17
本文介绍了使用Prim算法寻找加权无向图的最小生成树的方法,通过邻接矩阵表示图,并以0为起点逐步构建最小生成树。详细展示了算法过程及输出结果,包括从不同节点开始构建的最小生成树路径和总成本。

835

被折叠的 条评论
为什么被折叠?



