Prim算法实现最小生成树

这篇具有很好参考价值的文章主要介绍了Prim算法实现最小生成树。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.最小生成树是什么

对连通图进行遍历,过程中所经过的边和顶点的组合可看做是一棵普通树,通常称为生成树。
如果连通图G的一个子图是一棵包含G的所有顶点的树,则该子图称为G的生成树(SpanningTree)。
生成树是连通图的包含图中的所有顶点的极小连通子图。
图的生成树不惟一。从不同的顶点出发进行遍历,可以得到不同的生成树。
最小生成树(minimum spanning tree)其实就是一个生成树,不过它不同于一般的生成树,它的边权之和是最小的,即边权和最小的生成树。
同一个图的最小生成树也可以有很多个,但是其边权和肯定是一样的。

2.最小生成树的用途

最小生成树应用于图论知识的实际问题。生成树和最小生成树有许多重要的应用。

例如:要在n个城市之间铺设光缆,主要目标是要使这n个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低。这就需要找到带权的最小生成树。

3.Prim算法描述

将图中所有顶点分为两类:树顶点(已被选入生成树的顶点)和非树顶点(还未被选入生成树的顶点)。首先选择任意一个顶点加入生成树,接下来找出一条边添加到生成树,这需要枚举每一个树顶点到每一个非树顶点所有的边,然后找到最短的边加入到生成树中。一直重复直至所有顶点都加入生成树中。
算法的具体流程如下:

  1. 从任意一个顶点(假设选1)开始构造生成树,首先将顶点1加入生成树中,用一个一维数组book标记那些顶点已经加入到了生成树中。
  2. 用数组dis记录生成树到各个顶点的距离。最初生成树只有1号顶点,有直连边时,数组dis中存储的就是1号顶点到该顶点的边的权值,没有直连边的时候就是无穷大(INT_MAX),即初始化数组。
  3. 从数组dis中选出离生成树最近的顶点(假设为顶点j)加入到生成树中(在数组dis中的最小值)。再以j为中间点,更新生成树到每一个非树顶点的距离,如果dis[k] > e[j][k]则更新dis[k] = e[j][k]。
  4. 重复步骤3,直到生成树中有n个顶点为止。

4.Prim算法演示最小生成树过程

图的数据结构描述:
如下图所示,用一个二维矩阵graph表示边的顶点和边信息,例如graph[1][2] = 11表示顶点1到顶点2的权重是11.
一维数组book表示节点i是否被访问过,book[i] = 1表示节点i已经被访问,否则表示还没有被访问。
一维数组dis表示生成树到各个顶点的距离。

Prim算法实现最小生成树

初始化与图相关的所有数据结构,如下所示:

Prim算法实现最小生成树

Prim算法实现的具体步骤如下:

Prim算法实现最小生成树
Prim算法实现最小生成树

5.Prim算法实现

#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;

/*
* 测试用例
2 4 11
3 5 13
4 6 3
5 6 4
2 3 6
4 5 7
1 2 1
3 4 9
1 3 2
*/
class Prim
{
private:
    int vertice = 0;//顶点数
    int edge = 0;//边数
    vector<bool> book;//记录顶点i是否被遍历过
    vector<int> dis;//记录最短距离
    vector<vector<int>> graph;
    int sum = 0;//记录最小生成树权值总和
    int count = 0;//记录最小生成树中节点个数
    int index = 0;//记录dis中最小值的顶点

public:
    Prim(int x = 0, int y = 0) :vertice(x), edge(y)
    {
        graph.resize(vertice + 1);
        for (int i = 0;i <= vertice; i++)
        {
            graph[i].resize(vertice + 1,INT_MAX);
        }
        book.resize(vertice + 1, 0);
        dis.resize(vertice + 1, INT_MAX);
    }

    //图以及图相关的数据结构初始化
    void Init_Graph()
    {
        int u = 0, v = 0, w = 0;
        for (int i = 0; i < edge; i++)
        {
            cin >> u >> v >> w;
            graph[u][v] = w;
            graph[v][u] = w;//无向图的初始化
        }
        for (int i = 1; i <= vertice; i++)
        {
            if (graph[1][i] != INT_MAX)
            {
                dis[i] = graph[1][i];
            }
        }
        book[1] = true;
        cout << "1 -->";
        count++;
    }

    int Prim_Alg()
    {        
        while (count < vertice)
        {
            int min = INT_MAX;
            //找dis中的最小值
            for (int i = 1; i <= vertice; i++)
            {
                if (book[i] == false && dis[i] < min)
                {
                    min = dis[i];
                    index = i;
                }
            }
            cout << index << "-->";
            book[index] = true;
            count++;
            sum += dis[index];

            //扫描以index为到达的所有边,更新dis数组
            for (int i = 1; i <= vertice; i++)
            {
                if (book[i] == false && dis[i] > graph[index][i])
                {
                    dis[i] = graph[index][i];
                }
            }
        }
        return sum;
    }
};

int main()
{
    Prim prim(6,9); 

    cout << "请输入边的信息:" << endl;
    prim.Init_Graph();

    int sum = prim.Prim_Alg();
    cout << "NULL"<<endl<<"最小生成树权重:"<<sum << endl;
    return 0;
}

Prim算法实现最小生成树文章来源地址https://www.toymoban.com/news/detail-502869.html

END

到了这里,关于Prim算法实现最小生成树的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言实现最小生成树算法:Prim和Kruskal

    以下是使用C语言实现Prim算法生成最小生成树的代码: 注释如下: #include stdio.h 和 `#include #define V 5 定义了图中顶点的个数为5。 int minDistance(int dist[], int visited[]) 函数用于找到顶点集合中未访问的顶点中距离最小的顶点。输入参数 dist 用于存储顶点到最小生成树的距离,输入

    2024年02月03日
    浏览(32)
  • 考研算法复试刷题19天:Prim算法求最小生成树 【prim,最小生成树】

    参考博客:图解:什么是最小生成树? - 知乎 (zhihu.com)  总结下来的过程就是,一张图,我们将他化为树的形式,也就是生成树。那么最小生成树有是啥呢? 所谓一个 带权图 的最小生成树,就是原图中边的权值最小的生成树 ,所谓最小是指边的权值之和小于或者等于其它

    2024年02月07日
    浏览(48)
  • 贪心算法:最小生成树Prim算法

    👨‍🎓作者简介:一位喜欢写作,计科专业大二菜鸟 🏡个人主页:starry陆离 🕒首发日期:2022年5月31日星期二 🌌上期文章:动态规划:多重背包问题 📚订阅专栏:算法分析与设计 如果文章有帮到你的话记得点赞👍+收藏💗支持一下哦 这是大一暑假的c笔记,再一次写pri

    2024年02月01日
    浏览(38)
  • 最小生成树—Prim算法

    我们要讨论的问题是如何在一个 无向图 中找到它的最小生成树,虽然这个问题对有向图也有意义,但是处理起来更麻烦。 一个无向图 G 的最小生成树就是连接 G 上所有顶点的边构成的树,且这些边的总权值最低。当且仅当图是 连通的 才有最小生成树。 在无向图的最小生成

    2024年02月09日
    浏览(34)
  • Prim算法求最小生成树

    给定一张边带无权的无向图G = (V, E), n = |V|, m = |E|。由V中全部n个顶点和E中n - 1条边构成的无向连通子图被称为G的一课生成树。边的权值之和最小的生成树被称为无向图的最小生成树。 Prim算法总是维护最小生成树的一部分。最初,Prim算法仅确定1号节点属于最小生成树

    2024年02月12日
    浏览(30)
  • 最小生成树(Prim算法,Kruskal算法)

    (1)生成树: 如果在一个无向连通图不包含回路(连通图中不存在环),则为一个树 (2)最小生成树(minimal spanning tree): 在一个图所有生成树中,代价最小的生成树称为最小生成树 (3)生成树的代价: 在一个无向连通网中,生成树各边的权值之和称为该生成树的代价

    2024年02月08日
    浏览(27)
  • 最小生成树——Prim算法(详细图解)

    目录  最小生成树的概念   经典题目 prim算法简介  prim算法解析 (详细图解)  代码实现  代码实战 在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边,而 w(u, v) 代表此的边权重,若存在 T 为 E 的子集(即)且为无循环图,使得的 w(T) 最小,则此 T 为 G 的

    2023年04月09日
    浏览(27)
  • 图的最小生成树-Prim算法

    目录 问题引入  程序设计  程序分析 本节文章 【问题描述】 编写程序,利用带权无向图的邻接矩阵存储,实现图的最小生成树Prim算法。 【输入形式】 输入图的顶点序列及图的边的情况。如样例所示。边的输入以输入-1,-1,-1,作为结束。 0,1,6 表示对应的顶点及边是:

    2024年02月08日
    浏览(42)
  • 最小生成树——普利姆(Prim)算法

    构成连通网的最小代价生成树称为最小生成树(Minimun Cost Spanning Tree). 最小生成树可以运用到生活中,假如你是一位工程师,需要为一个镇的九个村庄架设通信网络做设计,村庄位置大值如下图:  其中 V0~V8 是村庄,之间连线的数字表示村与村间的可通达的直线距离,比如

    2024年02月04日
    浏览(32)
  • 最小生成树—Kruskal算法和Prim算法

    连通图:在无向图中,若从顶点v1到顶点v2有路径,则称顶点v1与顶点v2是连通的。如果图中任 意一对顶点都是连通的,则称此图为连通图。 生成树:一个连通图的最小连通子图称作该图的生成树。有n个顶点的连通图的生成树有n个顶点 和n-1条边。 最小生成树:构成生成树的

    2024年02月05日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包