一、实验要求与目的
- 熟悉贪心算法的基本原理与适用范围。
- 使用贪心算法编程,求解最小生成树问题。
二、实验内容
任选一种贪心算法(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
用贪心算法求解最小生成树
猜你喜欢
转载自blog.csdn.net/weixin_43442778/article/details/89604050
今日推荐
周排行