最小生成树

Posted 会宁狐狸

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小生成树相关的知识,希望对你有一定的参考价值。

 INTRODUCTION

一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。 最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。

--百度百科

概述

在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) 代表此的权重,若存在 T 为 E 的子集(即)且为无循环图,使得

的 w(T) 最小,则此 T 为 G 的最小生成树

技术图片

最小生成树其实是最小权重生成树的简称。

--百度百科

最小生成树的性质:

最小生成树性质:设G=(V,E)是一个连通网络,U是顶点集V的一个非空真子集。若(u,v)是G中一条“一个端点在U中(例如:u∈U),另一个端点不在U中的边(例如:v∈V-U),且(u,v)具有最小权值,则一定存在G的一棵最小生成树包括此边(u,v)。--百度百科

通俗来说

对于一个连通图,若已经求出最小生成树A,则若能找出最小生成树B与A不同

则这个图中,至少有两条边边权相等,且两条边在同一个环上,删去这两条边中的任意一条不影响原图的连通性,

且在生成树A,B中等边权的边的数量相等

 推论

 

对于一个连通图,将他制成一颗生成树,使他的最大边最小,则这棵树是该图的最小生成树

不存在比最小生成树中最大边i更小的边j,当j将i替换后原图联通,若替换后仍联通,则j的权值必定比i大

因为在求最小生成树时已经保证最小联通

最小生成树的求法:

1,Kruskal

大致思路在于将每一条边按照边权从小到大排序,之后按这个顺序扫一遍,若这条边的起点和终点尚未联通或间接联通,那加上这条边,把这两个点连起来,那么怎么判断联通呢?自然要靠并查集了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 using namespace std;
 6 int f[100086];
 7 struct edge
 8 {
 9     int from;
10     int to;
11     int weight;
12 };
13 int n, m;
14 int tot;
15 long long ans;
16 vector<edge>e;
17 int find(int x)//普通的并查集
18 {
19     if (f[x] == x)
20         return x;
21     else
22         return f[x] = find(f[x]);
23 }
24 void merge(int a, int b)
25 {
26     int x = find(a);
27     int y = find(b);
28     if (f[x] != f[y])
29         f[y] = x;
30 }
31 bool cmp(edge a, edge b)
32 {
33     return a.weight < b.weight;
34 }
35 int main()
36 {
37     cin >> n >> m;
38     for (int i = 1; i <= n; i++)
39         f[i] = i;//并查集初始化
40     for (int i = 1; i <= m; i++)
41     {
42         int x, y, z;
43         cin >> x >> y >> z;
44         edge t;
45         t.from = x;
46         t.to = y;
47         t.weight = z;
48         e.push_back(t);
49         t.from = y;
50         t.to = x;
51         e.push_back(t);
52     }
53     sort(e.begin(), e.end(), cmp);
54     for (int i = 0; i < e.size(); i++)
55     {
56         if (find(e[i].from) != find(e[i].to))
57         {
58             merge(e[i].from, e[i].to);
59             ans += e[i].weight;
60         }
61     }
62     cout << ans << endl;
63     return 0;
64 }

2,Prim

以上是关于最小生成树的主要内容,如果未能解决你的问题,请参考以下文章

最小生成树matlab代码Kruskal算法,用于二维网络生成

c语言最小生成树

最小生成树及Prim算法及Kruskal算法的代码实现

数据结构 图连通与最小生成树

次最小生成树 模版

图的最小生成树算法(图解+代码)| 学不会来看我系列