最小生成树(普利姆算法)

题目描述

【问题描述】用prim算法思想求一个给定无向连通网的最小生成树。

【输入形式】无向连通网的顶点数,起始顶点及无向连通网各边的权值。

【输出形式】第1行为顶点数,第2行为起始顶点;接着若干行为无向连通网各边的信息。0表示不存在顶点到自身的边,32767表示两个顶点之间不存在边。(样例输入的第1行表示图有6个顶点,第2行表示从顶点0出发)

【样例输入】

6

0

0  5  8  7  32767  3  

5  0  4  32767  32767  32767  

8  4  0  5  32767  9  

7  32767  5  0  5  32767  

32767  32767  32767  5  0  1  

3  32767  9  32767  1  0

【样例输出】

普里姆算法求解结果:

  边(0,5)权为:3

  边(5,4)权为:1

  边(0,1)权为:5

  边(1,2)权为:4

  边(4,3)权为:5

最小生成树的代价为:18


解题思路

  1. 选择一个起始节点作为最小生成树的起点。
  2. 将该起始节点加入最小生成树集合,并将其标记为已访问。
  3. 在所有与最小生成树集合相邻的边中,选择权重最小的边和它连接的未访问节点。
  4. 将该边和节点加入最小生成树集合,并将该节点标记为已访问。
  5. 重复步骤3和步骤4,直到最小生成树集合包含了图中的所有节点。

源代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#define MAX 100
#define INF 32767

void prim(int n, int start, int cost[][MAX], int dist[], int path[]) {
    int i, j, k, min, minid, sum = 0;

    // 初始化dist和path数组
    for (i = 0; i < n; i++) {
        dist[i] = cost[start][i];
        path[i] = start;
    }
    for (i = 1; i < n; i++) {
        min = INF;
        minid = -1;
        // 找出当前dist数组中最小值对应的顶点
        for (j = 0; j < n; j++) {
            if (dist[j] != 0 && dist[j] < min) {
                min = dist[j];
                minid = j;
            }
        }
        if (minid == -1) {
            printf("无法构成最小生成树\n");
            return;
        }
        // 将最小生成树的边输出
        printf("  边(%d,%d)权为:%d\n", path[minid], minid, min);
        sum += min;
        dist[minid] = 0;
        // 更新dist和path数组
        for (k = 0; k < n; k++) {
            if (dist[k] != 0 && cost[minid][k] < dist[k]) {
                dist[k] = cost[minid][k];
                path[k] = minid;
            }
        }
    }
    printf("最小生成树的代价为:%d\n", sum);
}

int main() {
    int n, start, i, j;
    int cost[MAX][MAX], dist[MAX], path[MAX];
    scanf("%d", &n);
    scanf("%d", &start);
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            scanf("%d", &cost[i][j]);
        }
    }
    printf("普里姆算法求解结果:\n");
    prim(n, start, cost, dist, path);
    return 0;
}

总结

        求取最小生成树算法,是数据结构图部分的经典算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想我记得写信

您的鼓励是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值