/**
* 书本:《算法分析与设计》
* 功能:实现用Prim算法实现寻找最小生成树
* 文件:PrimMixTree.cpp
* 时间:2015年1月4日19:42:57
* 作者:cutter_point
*/
#include <iostream>
#include <fstream> //文件输入输出流
using namespace std;
const int N = 6; //这个图是一个6*6的矩阵
const int inf = 9999;
ifstream fin("prim.txt"); //输入文件源
//核心算法
template<class T>
void Prim(int n, T c[][N+1]) //输入节点个数和图的矩阵
{
T lowcost[N + 1]; //记录S到V-S(N+1)的最短距离,记录c[j][closest]的最小权值,就是已经选中为最短路径的部分到没选中额部分的最短距离
int closest[N + 1]; //V-S中点j在S中的最近邻接顶点 ,这个是节点,上面那个是权值距离
bool s[N + 1];
s[1] = true;
//S就是最小生成树的组成
for (int i = 2; i <= n; ++i) //初始化所有的数组
{
lowcost[i] = c[1][i]; //就是1到其他节点的距离就是当前的最短距离,应为首先我们,默认从1开始
closest[i] = 1; //连接的是S中的1号节点,因为开始的时候S中只有1
s[i] = false; //首先从2开始都不是S中的元素
}
//开始寻找最小生成树
for (int i = 1; i < n; ++i) //一共还有5个节点
{
T min = inf; //初始是没有连接,所以是9999,假设是无穷
int j = 1; //标记这个是要新加入的节点
for (int k = 2; k <= n; ++k) //遍历所有的节点
if ((lowcost[k] < min) && (!s[k])) //找到还没有被选中的节点中,S到他们的距离是找到最小的一条lowcost[k]就是S中到k节点的最小值
{
min = lowcost[k]; //找到最小的一条路
j = k; //得到这个节点
}
//输入找到的路径
cout << "把" << j << "连接上" << closest[j] << endl;
s[j] = true; //把j节点加入到最小生成树中
//重新更新lowcost和closest
for (int k = 2; k <= n; ++k)
{
//S到k的距离和当前要连接的节点j到k相比那个小,把小的作为新的各个节点V-S到S的最小路径
if ((c[j][k] < lowcost[k]) && (!s[k])) //必须是外面没加入到最小生成树的节点
{
lowcost[k] = c[j][k]; //刷新S到V-S(k)的最短路径
closest[k] = j; //S和V-S连接最近节点的改变
}
}
}
}
int main()
{
int c[N + 1][N + 1]; //+1是为了后面输入的时候从1开始到6,而不是从0到5
cout << "图的矩阵是:" << endl;
for (int i = 1; i <= N; ++i)
{
for (int j = 1; j <= N; ++j)
{
fin >> c[i][j]; //把文件中的数据输入到数组中
cout << c[i][j] << "\t"; //输出看看
}
cout << endl;
}
cout << "生成最小生成树寻找次序:" << endl;
Prim(N, c);
return 0;
}
效果截图: