5471: 数据结构实验--图的最小代价生成树 prim

发布时间 2023-05-01 13:36:56作者: CRt0729

描述

 

 

求带权无向图的最小代价生成树。

 

 

 

 

输入

 

 

输入数据为多组,每组数据包含多行,第一行为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
*/