码迷,mamicode.com
首页 > 其他好文 > 详细

最小生成树 - Prim 和Kruskal

时间:2015-05-18 16:43:55      阅读:98      评论:0      收藏:0      [点我收藏+]

标签:算法      

最近有些忙,先把最小生成树的代码挂上,有时间将讲解补上。

在这里两个函数:Prim和Kruskal函数,分别是这两个算法的主算法代码。使用的图存储方式是邻接矩阵。

#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
#define MAX 100
#define INT_MAX 10000

#define min(x,y)(x<y?x:y)
typedef struct{
	int matrix[MAX][MAX]; //邻接矩阵
	int num;// 最大的顶点数
}Graph;
int InitNode;
Graph example; //实例图

// 初始化图
void initGraph(){
	int i,j;
	for(i=0;i<MAX;i++){
		for(j=0;j<MAX;j++){
			example.matrix[i][j]=INT_MAX;
		}
		
	}
	example.num=0;
}



void createPoint(){
	int i,j,val;
	initGraph();
	while(cin>>i>>j>>val){
		if(i==0 && j==0) break;
		example.matrix[i][j]=val;
		example.matrix[j][i]=val;
		example.num = max(example.num,i); 
		//这里偷了个懒,我这里假设顶点之间序号是连续的,没有点之间
		//序号跨很大的情况,如果需要的话,大家可以写一个函数改一下
		//这里。
		example.num = max(example.num,j);
	}
}

//输出最后的最短路径
void printResult(int *from,int *lowcost,int n){
	cout<<"--------------------------"<<endl;
	for(int i=1;i<=n;i++){
		if(i!=InitNode) cout<<from[i]<<"->"<<i<<":"<<lowcost[i]<<endl;
	}
}

void Prim(){
	int *S = new int[example.num+1]; //已选择集合
	int *lowcost = new int[example.num+1]; //最小权值
	int *processed = new int[example.num+1]; //记录已选择
	int *from = new int[example.num+1]; //记录从哪个结点到对应下标点的
	//数组初始化
	for(int i=0;i<=example.num;i++){
		lowcost[i] = INT_MAX;
	}
	memset(from,0,sizeof(from));
	memset(processed,0,sizeof(processed));
	//将初始点放入集合中
	int count = 1,NowProPoint = InitNode;
	S[count]=NowProPoint; processed[NowProPoint]=1;count++;

	while(count<=example.num){
		int minval = INT_MAX, minInd = -1;
		for(int i=1;i<=example.num;i++){
			if(processed[i]!=1){
				if(lowcost[i]>example.matrix[NowProPoint][i]){
					lowcost[i] = example.matrix[NowProPoint][i];
					from[i] = NowProPoint;
				}

				if(minval>lowcost[i]){
					minval = lowcost[i];minInd = i;
				}
			}
		}

		S[count]=minInd; processed[minInd]=1;count++;
		NowProPoint = minInd;

		//输出lowcost的变化过程
		cout<<"--------------------------"<<endl;
		for(int i=1;i<=example.num;i++){
			cout<<lowcost[i]<<" ";
		}
		cout<<endl;
	}
	printResult(from,lowcost,example.num);
}

void kruskal(){
	//这个kruskal算法使用堆的时间复杂度是o(eloge),但是因为用了邻接矩阵作为存储方式
	//所以是o(n3)。。
	int shortPath,x,y;
	int *processed = new int[example.num+1]; //联通分量
	
	//数组初始化
	for(int i=0;i<=example.num;i++){
		processed[i]=i;  //一开始每个节点为一个连通分量
	}

	int count = 1;
	cout<<"--------------------------"<<endl;
	while(count<example.num){
		shortPath = INT_MAX;x=-1;y=-1;
		for(int i=1;i<=example.num;i++){
			for(int j=1;j<=example.num;j++){
				if(shortPath>example.matrix[i][j] && (processed[i]!=processed[j])){
					shortPath = example.matrix[i][j];
					x= i ;y =j;
				}
			}
		}
		//将两个连通分量合并成一个
		for(int i=1;i<=example.num;i++){
			if(processed[i]==processed[x]) processed[i]=processed[y];
		}
		count++;
		//输出最短路径
		cout<<x<<"->"<<y<<":"<<shortPath<<endl;
	}
}
int main(){
	InitNode =1;
	createPoint();
	Prim();
	kruskal();
	return 0;
}


最小生成树 - Prim 和Kruskal

标签:算法      

原文地址:http://blog.csdn.net/u010006643/article/details/45823817

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!