描述
求带权无向图的最小代价生成树。
输入
输入数据为多组,每组数据包含多行,第一行为2个整数n,e,n为图的顶点数,e为边数,接下来是e行,每行3个整数,前两个整数是一个顶点对,代表一条边所依附的两个顶点,第3个整数是边的权值。
所有值不超过20。
输出
请使用prim算法生成一棵生成树(从顶点1出发,权值相同时从编号较小的顶点开始扩展),并输出为生成树的各条边及其权值。格式见样例。
样例输入
5 7
1 2 1
1 3 1
2 3 4
2 4 2
2 5 1
3 4 5
4 5 6
样例输出
1 2 1
1 3 1
2 5 1
2 4 2
#include<bits/stdc++.h> using namespace std; const int N=105; const int INF=0x3f3f3f3f; int lowc[N],vis[N],G[N][N],fa[N]; int Prim(int n) { vis[1]=1; for(int i=2;i<=n;i++)lowc[i]=G[1][i],fa[i]=1; for(int i=2;i<=n;i++) { puts("目前各个点的最短边为:"); for(int k=2;k<=n;k++) { printf("从 %d 到 %d 的边,距离为%d\n",fa[k],k,lowc[k]); } int minc=INF; int p=-1; for(int j=1;j<=n;j++) if(!vis[j]&&minc>lowc[j]) minc=lowc[j],p=j; printf("所有相连边里最短的是从 %d 到 %d ,距离为:%d,选%d作为中间点\n",fa[p],p,minc,p); vis[p]=1; for(int j=1;j<=n;j++) if(!vis[j]&&lowc[j]>G[p][j]) { printf("从%d点和%d点距离是%d小于从%d到%d的距离%d,故%d点的最短边距离更新为%d,相连的点是%d\n",p,j,G[p][j],fa[j],j,lowc[j],j,G[p][j],p); lowc[j]=G[p][j],fa[j]=p; } } } int main() { int n,e,u,v,w; while(scanf("%d%d",&n,&e)!=EOF) { memset(G,INF,sizeof(G)); memset(vis,0,sizeof(vis)); for(int i=0;i<e;i++) { scanf("%d%d%d",&u,&v,&w); G[u][v]=G[v][u]=w; } Prim(n); } return 0; } /* 6 10 1 2 6 1 3 1 1 4 5 2 3 5 2 5 3 3 4 5 3 5 6 3 6 4 4 6 2 5 6 6 */
标签:prim,lowc,vis,--,生成,int,fa,5471,顶点 From: https://www.cnblogs.com/jyssh/p/17366442.html