数据结构之最小生成树(普里姆算法)

1)普里姆算法

可取图中任意一个顶点v作为生成树的根,之后若要往生成树上添加顶点w,则在顶点v和顶点w之间必定存在一条边,并且

该边的权值在所有连通顶点v和w之间的边中取值最小。一般情况下,假设n个顶点分成两个集合:U(包含已落在生成树上

的结点)和V-U(尚未落在生成树上的顶点),则在所有连通U中顶点和V-U中顶点的边中选取权值最小的边。

例如:起始生成树上面就一个顶点。为了连通两个集合,在可选的边中,选择权值最小的。需要辅助数组,V-U中所有顶点。

具体实例如下图所示:求下图的最小生成树

我们以a点为起始点,此时的U集合={a},V-U到U集合的路径有a-b=4,a-c=2,取最小的a-c,所以将c点添加到U集合中,U={a,c}。

此时,V-U到U集合的路径有b-a=4,b-c=3,取最小,更新b点到U集合的最短路径为3,此外还有c-d=5,c-h=5,所以,取V-U到U集

合的最小值为b-c=3,将b点添加到U集合中。U={a,c,b}。此时V-U到U集合存在以下点:c-d=5,c-h=5,b-d=5(与现有的c-d=5一样,

所以不更新,仍旧采用c-d),b-e=9,取最小的,此时可以有两个选择,假设选择c-d,所以将d点添加到U集合中。U={a,c,b,d}。

此时V-U到U的路径,因为e-d=7<e-b=9,所以e点进行更新,更新为d-e=7;同理d-h=4<c-h=5,所以点h到U的路径更新为d-h=4。

新增加的路径为d-f和d-g。此时选择V-U到U集合的最短路径为d-h=4,所以将h添加到U集合,此时U={a,c,b,d,h}。依次不断选择

下一个距离U集合最短路径的点,并将其添加到U集合,直到将所以顶点添加完毕。实现过程如下图所示:

接下来的代码示例图:

代码如下:

  1 #include "stdafx.h"
  2 #include<iostream>
  3 #include<string>
  4 using namespace std;
  5
  6 #define MaxNum 10000
  7 typedef struct MGraph
  8 {
  9     string vexs[60];
 10     int arcs[100][100];
 11     int vexnum, arcum;
 12 }MGraph;
 13 typedef struct Closedge
 14 {
 15     string adjvex;
 16     int lowcost;
 17 }minside[100];
 18
 19 int locateVex(MGraph G, string u) //返回顶点u在图中的位置  
 20 {
 21     for (int i = 0; i < G.vexnum; i++)
 22         if (G.vexs[i] == u)
 23             return i;
 24     return -1;
 25 }
 26
 27 void CreateGraphUDG(MGraph &G)  //构造无向图  
 28 {
 29     string v1, v2;
 30     int w;
 31     int i, j, k;
 32     cout << "请输入顶点数和边数:";
 33     cin >> G.vexnum >> G.arcum;
 34
 35     cout << "请输入顶点:";
 36     for (i = 0; i < G.vexnum; i++)
 37         cin >> G.vexs[i];
 38
 39     for (i = 0; i < G.vexnum; i++)
 40         for (j = 0; j < G.vexnum; j++)
 41             G.arcs[i][j] = 10000;
 42
 43     cout << "请输入边和权值:" << endl;
 44     for (k = 0; k < G.arcum; k++)
 45     {
 46         cin >> v1 >> v2 >> w;
 47         i = locateVex(G, v1);
 48         j = locateVex(G, v2);
 49         G.arcs[i][j] = G.arcs[j][i] = w;
 50     }
 51
 52 }
 53
 54 int minimum(minside sz, MGraph G) //求sz中lowcost的最小值,返回序号  
 55 {
 56     int i = 0, j, k, min;
 57     while (!sz[i].lowcost)
 58         i++;
 59     min = sz[i].lowcost;
 60     k = i;
 61     for (j = i + 1; j < G.vexnum; j++)
 62     {
 63         if (sz[j].lowcost > 0 && min > sz[j].lowcost)
 64         {
 65             min = sz[j].lowcost;
 66             k = j;
 67         }
 68     }
 69     return k;
 70 }
 71
 72 void MiniSpanTree_PRIM(MGraph G, string u) //普里姆算法  
 73 {
 74     int i, j, k;
 75     minside closedge;
 76     k = locateVex(G, u);
 77     for (j = 0; j < G.vexnum; j++)
 78     {
 79         closedge[j].adjvex = u;
 80         closedge[j].lowcost = G.arcs[k][j];
 81     }
 82     closedge[k].lowcost = 0;
 83     cout << "最小生成树各边为:" << endl;
 84
 85     for (i = 1; i < G.vexnum; i++)
 86     {
 87         k = minimum(closedge, G);
 88         cout << closedge[k].adjvex << "-" << G.vexs[k] << endl;
 89         closedge[k].lowcost = 0;
 90         for (j = 0; j < G.vexnum; j++)
 91         {
 92             if (G.arcs[k][j] < closedge[j].lowcost)
 93             {
 94                 closedge[j].adjvex = G.vexs[k];
 95                 closedge[j].lowcost = G.arcs[k][j];
 96             }
 97         }
 98     }
 99 }
100
101 int main()
102 {
103     MGraph G;
104     CreateGraphUDG(G);
105     MiniSpanTree_PRIM(G, G.vexs[0]);
106     cout << endl;
107     return 0;
108 }

输出结果:

关于克鲁斯卡尔算法博主明天会更新,请耐心等待...

原文地址:https://www.cnblogs.com/Trojan00/p/8983207.html

时间: 2024-09-30 15:36:44

数据结构之最小生成树(普里姆算法)的相关文章

图-&gt;连通性-&gt;最小生成树(普里姆算法)

文字描述 用连通网来表示n个城市及n个城市间可能设置的通信线路,其中网的顶点表示城市,边表示两城市之间的线路,赋于边的权值表示相应的代价.对于n个定点的连通网可以建立许多不同的生成树,每一棵生成树都可以是一个通信网.现在,我们要选择这样一个生成树,使总的耗费最少.这个问题就是构造连通网的最小代价生成树(Minimum Cost Spanning Tree: 最小生成树)的问题.一棵生成树的代价就是树上各边的代价之和. 有多种算法可以构造最小生成树,其他多数都利用的最小生成的MST(minimum

数据结构-最小生成树-普里姆算法

转自https://blog.csdn.net/ZGUIZ/article/details/54633115 首先仍然是预定义: 1 #define OK 1 2 #define ERROR 0 3 #define Max_Int 32767 4 #define MVNum 100 5 6 typedef int Status; 7 typedef char VerTexType; 8 typedef int ArcType; 9 10 struct{ 11 VerTexType adjvex;

数据结构例程——最小生成树的普里姆算法

本文是[数据结构基础系列(7):图]中第11课时[最小生成树的普里姆算法]的例程. (程序中graph.h是图存储结构的"算法库"中的头文件,详情请单击链接-) #include <stdio.h> #include <malloc.h> #include "graph.h" void Prim(MGraph g,int v) { int lowcost[MAXV]; //顶点i是否在U中 int min; int closest[MAXV]

数据结构(五)图---最小生成树(普里姆算法)

一:最小生成树 (一)定义 我们把构造连通网的最小代价生成树称为最小生成树 (二)什么是最小生成树? 1.是一棵树 1)无回路 2)N个顶点,一定有N-1条边 2.是生成树 1)包含全部顶点 2)N-1条边都在图中 3.边的权重和最小 (三)案例说明 在实际生活中,我们常常碰到类似这种一类问题:如果要在n个城市之间建立通信联络网, 则连通n个城市仅仅须要n-1条线路.这时.我们须要考虑这样一个问题.怎样在最节省经费前提 下建立这个通信网.换句话说,我们须要在这n个城市中找出一个包括全部城市的连通

46. 蛤蟆的数据结构笔记之四十六普里姆算法

46. 蛤蟆的数据结构笔记之四十六普里姆算法 本篇名言:"手莫伸 ,伸手必被捉.党与人民在监督 ,万目睽睽难逃脱.汝言惧捉手不伸 ,他道不伸能自觉 , 其实想伸不敢伸 ,人民咫尺手自缩.-- 陈毅" 连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边.所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接起来,并且使得权值的和最小.构造连通网的最小代价生成树,即最小生成树(Minimum Cost Spanning Tree). 找连通图的最

ACM第四站————最小生成树(普里姆算法)

对于一个带权的无向连通图,其每个生成树所有边上的权值之和可能不同,我们把所有边上权值之和最小的生成树称为图的最小生成树. 普里姆算法是以其中某一顶点为起点,逐步寻找各个顶点上最小权值的边来构建最小生成树. 其中运用到了回溯,贪心的思想. 废话少说吧,这个其实是一个模板,直接套用就好!直接上题吧!这些东西多练就好! 一.最小生成树: 题目描述 求一个连通无向图的最小生成树的代价(图边权值为正整数). 输入 第 一行是一个整数N(1<=N<=20),表示有多少个图需要计算.以下有N个图,第i图的第

普里姆算法,克鲁斯卡尔算法,迪杰斯特拉算法,弗洛里德算法

做数据结构的课程设计顺便总结一下这四大算法,本人小白学生一枚, 如果总结的有什么错误,希望能够告知指正 普里姆算法如图所示prim 找出最短的边,再以这条边构成的整体去寻找与之相邻的边,直至连接所有顶点,生成最小生成树,时间复杂度为O(n2) 克鲁斯卡尔算法如图所示kruskal 克鲁斯卡尔算法,假设连通网N=(N,{E}),则令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),图中每个顶点 自成一个连通分量.在E中选择代价最小的边,若该边依附的定顶点落在T中不同的连通分量上,

普里姆算法-prim

算法代码: C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 /* Prim算法生成最小生成树  */ void MiniSpanTree_Prim(MGraph MG) { int min, i, j, k; int adjvex[MAXVEX];/* 

普里姆算法介绍

普里姆(Prim)算法,和克鲁斯卡尔算法一样,是用来求加权连通图的最小生成树的算法. 基本思想 对于图G而言,V是所有顶点的集合:现在,设置两个新的集合U和T,其中U用于存放G的最小生成树中的顶点,T存放G的最小生成树中的边. 从所有u?U,v?(V-U) (V-U表示出去U的所有顶点)的边中选取权值最小的边(u, v),将顶点v加入集合U中,将边(u, v)加入集合T中,如此不断重复,直到U=V为止,最小生成树构造完毕,这时集合T中包含了最小生成树中的所有边. 普里姆算法图解 以上图G4为例,