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

什么是生成树呢?

一个连通图的生成树是指一个极小连通子图, 它含有图中的全部顶点,但只有足以构成一棵树的n-1条边。

什么是最小生成树?

在一个连通图的所有生成树中,各边的代价之和最小的那棵生成树称为该连通图的最小代价生成树(MST), 简称最小生成树。

求最小生成树有两种算法,本文讲prim算法。

简略证明

使用反证法证明

设一棵最小生成树T不包含最短边a,将a加入最小生成树T中,书中必定构成一个包含a的回路,而回路中必定有边比a大(因a为最短边),则删除比a大的边得到一棵比原先T更小的树T1,而T1才是最小生成树,则与假设矛盾,证明成立。

prim算法

将树的所有点划分为两个集合U 和 V

每次选一个最小代价的点从V加入U中,然后更新V中的点到U的最小代价,周而复始直到V为空。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define MAX_VERTEX_NUM 20
 4 #define INFINTY 32768
 5 typedef int AdjType;//权值类型
 6 typedef enum{DG, DN, UDG, UDN} GraphKind;
 7 typedef char VertexData;
 8 //边集
 9 typedef struct ArcNode{
10     AdjType adj;
11     //Other info
12 }ArcNode;
13 typedef struct{
14     VertexData vertex[MAX_VERTEX_NUM];
15     ArcNode arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
16     int vexnum, arcnum;
17     GraphKind kind;
18 }AdjMatrix;
19 struct{
20     int adjvex;
21     int lowcost;
22 }closedge[MAX_VEX_NUM];
23
24 MiniSpanTree_Prim(AdjMatrix gn, int u){
25     closedge[u].lowcost = 0;
26     for(int i = 0; i< gn.vexnum; i++)       //初始化
27     if(i != u){
28         closedge[i].adjvex = u;
29         closedge[i].lowcost = gn.arcs[u][i].adj;
30     }
31     for(int e = 1; i < = gn.vexnum-1;e++){
32         int v = Minium(closedge); //the minium cost from V to U
33         int u = closedge[v].adjvex;
34        // printf();
35        closedge[v].lowcost = 0; //add v to U
36        for(int i = 0; i< gn.vexnum; i++)
37        if(gn.arcs[v][i].adjgn.arcs[v][i].adj < closedge[i].lowcost){
38         closedge[i].lowcost = gn.arcs[v][i].adj;
39         closedge[i].adjvex = v;
40        }
41     }
42
43 }

原文地址:https://www.cnblogs.com/19990219073x/p/10048909.html

时间: 2024-11-01 12:53:23

图的最小生成树(普利姆prim算法)的相关文章

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

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

POJ-2421-Constructing Roads(最小生成树 普利姆)

Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26694   Accepted: 11720 Description There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two

普里姆Prim算法 - 图解最小生成树

我们在图的定义中说过,带有权值的图就是网结构.一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边.所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接起来,并且使得权值的和最小.综合以上两个概念,我们可以得出:构造连通网的最小代价生成树,即最小生成树(Minimum Cost Spanning Tree). 找连通图的最小生成树,经典的有两种算法,普里姆算法和克鲁斯卡尔算法,这里介绍普里姆算法. 为了能够讲明白这个算法,我们先构造网图的邻接矩阵,

普里姆(Prim)算法

1 /* 2 普里姆算法的主要思想: 3 利用二维数组把权值放入,然后找在当前顶点的最小权值,然后走过的路用一个数组来记录 4 */ 5 # include <stdio.h> 6 7 typedef char VertexType;//定义顶点类型 8 typedef int EdgeType;//定义边上的权值类型 9 # define MAX_VERTEX 100//最大顶点个数 10 # define INFINITY 65535//用65535代表无穷大 11 12 typedef

图的最小生成树(二)—Prim算法

上一篇中写了图的最小生成树求法一--Kruskal算法 http://blog.csdn.net/wtyvhreal/article/details/43526695 这一篇中用另外一种方法来求解图的最小生成树,Prim算法. 图中随便选一个顶点开始,看看这个顶点有哪些边,在它的边中找一条最短的.1号有1-2,1-3,其中1-2短,选择1-2.通过它把1和2连接在一起.接下来开始枚举1和2号顶点所有的边,看看哪些边可以连接到没有被选中的顶点,并且边越短越好. Prim算法的基本思路: 将图中的所

最小生成树——普利姆 克鲁斯卡尔

最小生成树 生成树定义:是原图的一个极小连通子图,含有原图的全部顶点,但只有n-1条边.它连通但边只有n-1,也就是说任意让两点连边必定成环,不过这结论好像没啥用. 最小生成树:对于一张图的生成树可能有多种,对于边权和最小的一种就是最小生成树了. prim算法 首先首先,我们来几个标识,原图是N={V,E},TE是N上最小生成树的边集,然后有个已选点集合U,那么未选点集就是V-U了. 首先,先来个起点,加入到U里面. 然后,在所以边(a,b),a属于U,b属于V-U里面,找一条权值最小的边(a0

图的最小生成树之普里姆Prim算法

源代码如下: #include<iostream> using namespace std; #define MAX_VERTEX_NUM 20 #define infinity 9 typedef int QElemType; typedef int EdgeData; typedef char VertexData; typedef struct { VertexData verlist[MAX_VERTEX_NUM]; //顶点表 EdgeData edge[MAX_VERTEX_NUM

最小生成树普利姆算法

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX 20#define INFINITY  0x7ffffffftypedef struct{    int U[MAX][MAX];    char adj[MAX][10];    int vexnum, arcnum;}Graph;typedef struct{    char

最小生成树 - 普利姆算法

#include<cstdlib> #include<cstdio> #include<cstring> #define MAXVEX 100 #define INFINITY 65535 typedef struct { char vexs[MAXVEX]; int arc[MAXVEX][MAXVEX]; int numVextexes,numEdges; }MGraph; void CreateGraph(MGraph *G){ int i,j,k,w; prin