最小生成树 (Kruscal 、prime)

来源:互联网 发布:优化营商环境宣传口号 编辑:程序博客网 时间:2024/06/17 11:24

Kruscal:

/*思想:该算法每次从所有未使用边中,找出权值最小的边,加入到生成树中,直到加入V-1条边(V是顶点数),构成一颗MST。*/#include<iostream>#include<algorithm>#include<string.h>using namespace std;typedef struct {int u,v;int w;}Edge;Edge e[1010];int fa[1010];bool myCompare(const Edge &a,const Edge &b){if(a.w<b.w) return true;else return false;}int find_fa(int n)           //并查集中的查找 {if(fa[n]==0)  return n;        //若根节点一样,则“忽略”该边 else return find_fa(fa[n]);    //若根节点不同,则将某一棵树的根连到另一棵树的根上 }int uion(int r1,int r2)         //并查集中的合并 {r1=find_fa(r1);r2=find_fa(r2);if(r1==r2) return 0;if(r1<r2)   fa[r2]=r1;else fa[r1]=r2;return 1;}int main(){int n,p;int sum,count;while (1){printf("请输入点的数量和边的数量:\n"); scanf("%d%d",&n,&p);printf("请输入每条边的详情:两顶点和权值\n");for(int i=1;i<=p;i++)  scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);sort(e+1,e+1+p,myCompare);  //将边权值大小从小到大排序 memset(fa,0,sizeof(fa));sum=0; count=1;for(int i=1;i<=p;i++)  // 查找每条边中相连的两点间是否已经加入了最小生成树中 {if(uion(e[i].u,e[i].v)) {sum+=e[i].w;count++;}if(count==n)  break;}printf("最小生成树权值和为:  %d\n",sum);}return 0;}/*input.txt:9141 2 41 8 82 3 82 8 113 4 73 6 43 9 24 5 94 6 145 6 106 7 27 8 17 9 68 9 7结果:37 */

prime:

#include<iostream>#include<string.h>#define INF 1000000;using namespace std;int arr[1010][1010];int dis[1010],vis[1010]; //dis[]记录的是起点经过中间点后到达 i点的最短距离 int main(){int n,p;int u,v,w,rec;int sum,min;while (1){sum=0;cout<<"请输入点、边的数量:"<<endl;scanf("%d%d",&n,&p);for(int i=0;i<n;i++)for(int j=0;j<n;j++)   arr[i][j]=INF; for (int i=0;i<p;i++)    //用矩阵建图 {scanf("%d%d%d",&u,&v,&w);arr[u-1][v-1]=arr[v-1][u-1]=w;}for(int i=0;i<n;i++)   dis[i]=arr[0][i];memset(vis,0,sizeof(vis));vis[0]=1;dis[0]=0;for(int i=1;i<n;i++)         //这里 循环 n-1次,确定 n-1条边,否则若为n,则出错 { min=INF;              //dis[i]为INF时代表不能与根节点相连 for(int j=0;j<n;j++)   //若该点未连到树中,找到此时最小的权值点     if( !vis[j]&&dis[j]<min )    {min=dis[j];rec=j;}sum+=min;cout<<"sum=  "<<sum<<endl;//计算sum的值,代表连到当前点的总权值 vis[rec]=1;for(int j=0;j<n;j++)   //更新dis[],使通过rec点可以与根节点相连的 dis[]更新 {if(!vis[j]&&dis[j]>arr[rec][j])dis[j]=arr[rec][j];}}for(int i=0;i<n;i++) cout<<dis[i]<<"  ";cout<<endl;printf("sum=  %d\n",sum);}return 0;} 


原创粉丝点击