利用普里姆算法求解最小生成树,写出步骤或画图表示过程。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用普里姆算法求解最小生成树,写出步骤或画图表示过程。相关的知识,希望对你有一定的参考价值。

利用普里姆算法求解最小生成树,写出步骤或画图表示过程。

参考技术A <1,6>边长度未知,这里看成无穷大。
历次循环中,选择两端点分别在U,V中的边中长度最小者,
具体如下:
1. 将1加入U中,其余点加入V中。
2. 选择边<1,7>,将7加入U中,从V中除去该点。
3. 选择边<7,6>,将6加入U中,从V中除去该点。
4. 选择边<1,2>,将2加入U中,从V中除去该点。
5. 选择边<2,3>,将3加入U中,从V中除去该点。
6. 选择边<2,4>,将4加入U中,从V中除去该点。
7. 选择边<2,5>,将5加入U中,从V中除去该点。
结束。由上述六条边组成的树为求得的最小生成树。本回答被提问者和网友采纳

最小生成树

  这篇博客是关于图论中的最小生成树,在这里我们先简单介绍最小生成树的概念:一个图中,选取总代价最小的边使得所有点都连通。由此得到的结果必然是一棵树,同时需要注意一个图的最小生成树不具有唯一性。下面介绍求最小生成树的一种方法:普里姆算法求最小生成树。

  普里姆算法正确性可以使用反证法进行证明,这里不进行展开。

  普里姆算法的核心为以下步骤:

  (1)使用一个d数组用于存储各个节点到树的距离,初始化d数组为无穷大。使用一个book数组用于区分某个节点是树节点还是非树节点,book数组初始化为false。首先从任意一个顶点开始构造树,按照习惯从第1号节点开始构造树,将d[1] = 0,book[1] = true。

  (2)更新与1号节点相连的非树节点到树的距离,也就是更新d数组,更新条件为:如果i节点到树的距离比d[i]中存储的距离小,那么更新d[i]为更小的值。

  (3)遍历更新后的d数组,找到非树节点中距离树最小的节点,将这个节点加入树中。

  (4)重复步骤1、2、3,直到生成树中有n个节点为止。

  下面为实现代码:

  

#include <iostream>
#include <cstdio>
using namespace std;

const int MAXN = 5001;
const int MAXM = 20001;

struct Line {
    int p;
    int next;
    int v;
};

struct Node {
    int dis;
    bool book;
};

Line line[MAXM * 2];
Node node[MAXN];
int h[MAXN];

int n, m, x, y, v, now, ans;

void add(int x, int y, int v, int lID) {
    line[lID].p = y;
    line[lID].v = v;
    line[lID].next = h[x];
    h[x] = lID;
}

int find() {
    int k = 0;
    for(int i = 1; i <= n; i++) {
        if(!node[i].book) {
            if(k == 0 || node[i].dis < node[k].dis) {
                k = i;
            }
        }
    }
    return k;
}

void update(int now) {
    int k = h[now];
    int p;
    while(k) {
        p = line[k].p;
        if(!node[p].book) {
            if(node[p].dis > line[k].v) {
                node[p].dis = line[k].v;
            }
        }
        k = line[k].next;
    }
}

int main() {
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= m; i++) {
        scanf("%d %d %d", &x, &y, &v);
        add(x, y, v, 2 * i - 1);
        add(y, x, v, 2 * i);
    }
    for(int i = 1; i <= n; i++) {
        node[i].book = false;
        node[i].dis = (1 << 31) - 1;
    }

    node[1].book = true;
    node[1].dis = 0;
    ans = 0;
    update(1);

    for(int i = 1; i < n; i++) {
        now = find();
        node[now].book = true;
        ans += node[now].dis;
        update(now);
    }
    printf("%d", ans);
    return 0;
}

 

 

   圆满结束。

以上是关于利用普里姆算法求解最小生成树,写出步骤或画图表示过程。的主要内容,如果未能解决你的问题,请参考以下文章

克鲁斯卡尔算法

使用克鲁斯卡尔算法为以下无向图构造出一棵最小生成树,请画出构造的每一步骤

matlab如何画出最小生成树

最小生成树

最小生成树

最小生成树算法(克鲁斯卡尔算法和普里姆算法)