用贪心算法求解最小生成树

一、实验要求与目的

  1. 熟悉贪心算法的基本原理与适用范围。
  2. 使用贪心算法编程,求解最小生成树问题。

二、实验内容

任选一种贪心算法(Prim或Kruskal),求解最小生成树。对算法进行描述和复杂性分析。

编程实现,并给出测试实例

三、实现思想

Prim:S、V为两个集合,S中初始为{1},V中包含了所有的顶点,然后从V-S中选出和S中顶点距离最近的顶点j,并将j添加到S中。设置两个数组closest和lowcost。对于每个j属于V-S,closet[j]就是j在S中的邻接点,它于S中其他邻接点k相比较有v[j][closet[j]]<=v[j][k],其中lowcost[j]的值就是v[j][closest]。最后lowcost存储的就是相应的最小生成树的权值,而对于每个顶点,closest中可以找到最小生成树所对应的边。

四、实现代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define mmax 100
#define maxt 100000000
int v[mmax][mmax];

void Prim(int n){
	int low[mmax];// 
	int clo[mmax];
	bool s[mmax];//判断该节点是否在S中 
	s[1]=true;
	for(int i=2;i<=n;i++){
		low[i]=v[1][i];//初始化 
		clo[i]=1;
		s[i]=false;
	}
	for(int i=1;i<n;i++){//对剩余的n-1个顶点进行操作 ,此处的i并无实际意思,只是起到一个记录变量的作用 
		int min=maxt;
		int j=1;
		for(int k=2;k<=n;k++)//从V-S中找到S中边权最小的节点 
			if((low[k]<min)&&(!s[k])){
				min=low[k];
				j=k;
			}
			cout<<j<<" "<<clo[j]<<":"<<low[j]<<endl;
			s[j]=true;
			for(int k=2;k<=n;k++){//调整low中的值,加入j节点之后,使得两个集合中的距离最小 
				if((v[j][k]<low[k])&&(!s[k])){
					low[k]=v[j][k];
					clo[k]=j;
				}
			}
		
	}
} 

int main()
{
	int n,m;//n vertexs and m edges
	cin>>n>>m;
	int ii,jj,tt;
	for(int i=0;i<=n;i++){
		for(int j=0;j<=n;j++)
		v[i][j]=maxt;
	}
	for(int i=0;i<m;i++){
		cin>>ii>>jj>>tt;
		v[ii][jj]=tt;
		v[jj][ii]=tt;
	}
	Prim(n);
	return 0;
}

//6 10
//1 2 6
//1 4 5
//1 3 1
//2 3 5
//2 5 3
//3 4 5
//3 5 6
//3 6 4
//4 6 2
//5 6 6

发布了43 篇原创文章 · 获赞 23 · 访问量 5306

猜你喜欢

转载自blog.csdn.net/weixin_43442778/article/details/89604050