prim算法(未优化版)

N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。

Input
第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000)
第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
Output
输出最小生成树的所有边的权值之和。
Sample Input
9 14
1 2 4
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 9 7
2 8 11
3 9 2
7 9 6
3 6 4
4 6 14
1 8 8
Sample Output
37


#include<stdio.h>
#include<string.h>
int a[1005][1005],dis[1005],vis[1005]={0}; //a用来存放:某点-某点的权值。
int indx,ans=0;                            //dis存放:当前到达的点到所有点的权值。
int n,m;                                   //vis标记走过的点。

void prim()
{
    int i,j,temp=9999999,ans=0;

    for(i=0;i<=n;i++)
        dis[i]=a[1][i];

    vis[1]=1;

    for(i=2;i<=n;i++)
    {
        temp=999999; //存储最小权值边。
        indx=0;
        for(j=0;j<=n;j++)
            if(dis[j]<temp && !vis[j])  //找出当前点到其他点 最小且没有走过的边的权值。
            {
                temp=dis[j];
                indx=j; //indx表示走到的点。
            }

        vis[indx]=1;
        ans+=temp;  //将最小边逐个相加。

        for(j=0;j<=n;j++)
            if(!vis[j] && a[indx][j]<dis[j])  //走到下一个点后更新权值。
                dis[j]=a[indx][j];            //注意:如果当前点比上一点到同一个点的权值大则不更新
                                              //例如 1-3权值为3 从1走到2后 2-3的权值为5 则不更新。
    }

        printf("%d\n",ans);
}
int main()
{
    int i,j,x,y,v;
    while(scanf("%d%d",&n,&m)!=EOF)
    {

        for(i=0;i<=n;i++)
            for(j=0;j<=n;j++)
                a[i][j]=999999;


        memset(vis,0,sizeof(vis));

        for(i=0;i<m;i++)
        {
            scanf("%d%d%d",&x,&y,&v);
            if(a[x][y]>v)
                a[x][y]=a[y][x]=v;
        }
        prim();
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值