最小生成树

合集下载

最短路径与最小生成树的区别

最短路径与最小生成树的区别

最短路径与最小生成树的区别

最短路径和最小生成树是算法中的两个重要概念,它们在图论中有广泛的应用。虽然它们都涉及到图中的路径和边权值,但是它们的目标和实现方式有着很大的不同。

最短路径算法的目标是找到从起点到终点的最短路径,其中路径的长度是通过边上的权值来定义的。最常见的最短路径算法有Dijkstra算法和Bellman-Ford算法。Dijkstra算法可以处理无向图或有向图上的最短路径问题,但是它要求图中所有边的权值都为非负数。Bellman-Ford算法则可以处理负权边的情况,但是它的时间复杂度比Dijkstra算法高。

最小生成树算法的目标是找到一棵包含图中所有顶点的树,使得树的所有边的权值之和最小。最常见的最小生成树算法是Prim算法和Kruskal算法。Prim算法是基于点的贪心算法,从一个起点开始,每次向树中添加距离最近的点,直到所有点都被添加进去。Kruskal 算法则是基于边的贪心算法,每次添加边时,只考虑是否形成环和边的权值大小。

因此,最短路径算法和最小生成树算法虽然都涉及到图中的路径和边权值,但是它们的目标和实现方式有着很大的不同。最短路径算法是寻找从起点到终点的最短路径,而最小生成树算法是构建一棵包含所有顶点的树,使得树的所有边的权值之和最小。

- 1 -

最小生成树matlab代码

最小生成树matlab代码

最小生成树

简介

最小生成树(Minimum Spanning Tree)是图论中的一个重要概念。它是一种用于

连接所有节点的树,同时使得树中边的权值之和最小。最小生成树在许多领域中都有广泛的应用,例如网络设计、电力传输、交通规划等。

算法

Kruskal算法

Kruskal算法是一种常用的解决最小生成树问题的算法。它的基本思想是通过不断

选择图中权值最小的边,并且保证这些边不会形成环,直到选择了足够多的边为止。具体步骤如下:

1.初始化一个空的最小生成树集合。

2.将图中所有边按照权值从小到大排序。

3.遍历排序后的边,如果当前边不会导致最小生成树形成环,则将该边添加到

最小生成树集合中。

4.最终得到的最小生成树集合即为所求。

Prim算法

Prim算法是另一种解决最小生成树问题的经典算法。它的基本思想是从一个起始

节点开始,逐步扩展最小生成树,直到覆盖所有节点。具体步骤如下:

1.初始化一个空的最小生成树集合。

2.随机选择一个起始节点,并将其加入到最小生成树集合中。

3.在最小生成树集合和图的剩余节点之间找到连接两部分的最小权值边,将该

边和连接的节点加入到最小生成树集合中。

4.重复步骤3,直到最小生成树覆盖了所有节点。

应用场景

网络设计

最小生成树在网络设计中有着广泛应用。例如,在计算机网络中,我们希望通过最小的成本将所有节点连接起来。最小生成树提供了一种方法来实现这一目标,通过构建一个权值最小的树形网络,可以节省物理资源,提高网络传输效率。

电力传输

在电力传输领域,最小生成树被用于设计最优的电力传输网络。通过选择最小的成本边连接所有电力站点,可以减少电力传输的总成本,并优化电力的分布。

最小生成树聚类算法

最小生成树聚类算法

最小生成树聚类算法

引言:

聚类是数据分析的重要方法之一,它通过将相似的对象分组来发现数

据集中的隐藏模式和结构。在聚类算法中,最小生成树聚类算法是一种基

于最小生成树(Minimum Spanning Tree,简称MST)的聚类方法。它通

过在数据点之间构建最小生成树来确定聚类结果。本文将详细介绍最小生

成树聚类算法的原理、步骤和应用。

一、最小生成树聚类算法原理

1.将数据集中的每个对象看作一个节点,并计算每对节点之间的相似

度(如欧氏距离、余弦相似度等)。将相似度转化为距离度量,如将相似

度映射到0-1之间的距离。

2.基于节点之间的距离建立完全图,图的节点集为数据集的节点集。

3. 使用最小生成树算法从完全图中生成最小生成树。最小生成树是

指连接图中所有节点,且总权重最小的树。常用的最小生成树算法有

Prim算法和Kruskal算法。

4.对生成的最小生成树进行剪枝操作,将权重较大的边删除,得到聚

类结果。剪枝操作的依据可以是设定的阈值或者根据聚类结果的评估指标

进行评估选择。

二、最小生成树聚类算法步骤

1.输入数据集,将每个对象看作一个节点,并计算节点之间的相似度。

2.将相似度转化为距离度量,建立完全图,节点集为数据集的节点集。

3.使用最小生成树算法生成最小生成树。

4.对生成的最小生成树进行剪枝操作,删除权重较大的边。

5.根据剪枝后的最小生成树,将剩余的边分成若干个子图,每个子图

表示一个聚类簇。

6.输出聚类结果。

三、最小生成树聚类算法应用

1.社交网络分析:对社交网络中的用户进行聚类,可以帮助发现社交

网络中的社区结构和关键用户。

最小生成树(Kruskal算法)

最小生成树(Kruskal算法)

�初始化:令 U={Ø},TE={Ø}。从 V 中取出一个顶点 u0 放入生成树的顶点集 U 中,作为
-1-
第一个顶点,此时 T = ({u0 }, {φ }) ;
�从 u ∈ U , v ∈ (V − U ) 的边(u,v)中找一条代价最小的边 (u * , v* ) ,将其放入 TE 中,并
将 v 放入 U 中;
-5-
//函数申明 void CreatGraph(MGraph *); void sort(edge* ,MGraph *); void MiniSpanTree(MGraph *); int Find(int *, int ); void Swapn(edge *, int, int); void CreatGraph(MGraph *G)//构造图 { int i, j,n, m; printf("请输入城市数及边数:"); scanf("%d %d",&G->vexnum,&G->arcnum); for (i = 1; i <= G->vexnum; i++)//初始化图 { for ( j = 1; j <= G->vexnum; j++) { G->arc[i][j].adj = G->arc[j][i].adj = 0; } } printf(" 请输入有道路连通的 2 个城市及他们之间的造价费用 ( 城市 1 用):\n"); for ( i = 1; i <= G->arcnum; i++)//输入边和费用 { scanf("%d %d",&n,&m); G->arc[n][m].adj = G->arc[m][n].adj = 1; scanf("%d",&G->arc[n][m].weight); } printf("邻接矩阵为:\n"); for ( i = 1; i <= G->vexnum; i++) { for ( j = 1; j <= G->vexnum; j++) { if(G->arc[i][j].adj==1) printf("%d ",G->arc[i][j].weight); else printf("%d ",G->arc[i][j].adj); G->arc[j][i].weight=G->arc[i][j].weight; } printf("\n"); } } void sort(edge edges[],MGraph *G)//对权值进行排序 { int i, j;

图论中的树与树的性质

图论中的树与树的性质

图论中的树与树的性质

图论是研究图及其性质的数学分支。在图论中,树是一种特殊的无环连通图,它具有许多重要的性质和应用。本文将介绍图论中树以及树的性质的相关内容。

一、树的定义与基本性质

树是一个连通且无环的无向图。具体定义如下:

1. 一个只有一个顶点的图是一个树。

2. 一个连通的图,如果删除任意一条边,则图不再连通,那么该图就是一个树。

树具有以下基本性质:

1. 一棵树有且只有一个连通分量。

2. 在一棵树中,任意两个顶点之间存在唯一路径。

3. 一棵树的边数比顶点数少1。

树的性质使得其在各个领域有着广泛的应用。下面将介绍树的一些重要性质。

二、树的性质

1. 最小生成树

最小生成树是指在一个带权图中,找到一个树,使得该树的边的权值之和最小。常用的最小生成树算法有Prim算法和Kruskal算法。最小生成树在网络设计、电力传输等领域有着重要的应用。

2. 无向树与有向树的转化

无向树可以通过给每条边赋予方向而转化为有向树,同样,有向树也可以通过移除边的方向而转化为无向树。

3. 树的直径

树的直径是指树中任意两个顶点之间的最长路径。求树的直径的算法可以通过两次BFS或DFS来实现。树的直径问题在网络拓扑、动态规划等领域有重要应用。

4. 中心与半径

树的中心定义为树中顶点到其他所有顶点的距离之和最小的顶点。树的半径定义为树中顶点到离其最远的顶点的距离。中心和半径是树中的重要概念,它们在设计网络、发现故障等方面有着重要应用。

5. 树的遍历

树的遍历是指按照一定规则来访问树的所有顶点。常用的树的遍历算法有深度优先搜索(DFS)和广度优先搜索(BFS)。树的遍历在路径搜索、关系分析等方面有广泛应用。

最小生成树名词解释

最小生成树名词解释

最小生成树名词解释

最小生成树是一种用于解决图论中最小连接问题的算法,它在一个给定的连通图中寻找一个子图,该子图包含所有顶点,且边的权重之和最小。

在最小生成树中,只有图中的一部分边被选中,以连接图中的所有顶点,并且这些边的权重之和最小。换句话说,最小生成树是图中的一棵树,它连接了图中的所有顶点,并且其边的权重之和最小。

最小生成树经常被应用于网络设计、城市规划、电网建设等领域。通过找到最小生成树,可以有效地构建具有最小成本的网络或路线,并优化资源的分配。

常见的最小生成树算法有Prim算法和Kruskal算法,它们通过不同的策略来选择连接顶点的边,最终得到最小生成树。最小生成树的概念和应用在实际生活中具有重要意义,可以帮助优化各种资源的利用和规划。

高项 最小生成树步骤

高项 最小生成树步骤

高项最小生成树步骤

最小生成树(Minimum Spanning Tree,简称MST)是一种用于连接一个无向连通图的所有顶点的树,同时保证树上的边权重之和最小。

以下是Kruskal算法的步骤,它是一种常用的求解最小生成树的算法:

1. 初始化一个空的最小生成树集合。

2. 将图中的所有边按照权重从小到大进行排序。

3. 依次遍历排序后的边,如果当前边连接的两个顶点不在同一个连通分量中,则将该边加入最小生成树集合,并将这两个顶点所在的连通分量合并。

4. 重复步骤3,直到最小生成树集合中的边数达到了图中顶点数减1为止。

另外,还有Prim算法可以用来求解最小生成树。以下是Prim算法的步骤:

1. 选择一个起始顶点,并将其加入最小生成树集合。

2. 将起始顶点的所有邻接边加入一个边集合。

3. 从边集合中选取权重最小的边,将该边加入最小生成树集合,并将该边连接的顶点加入最小生成树集合。

4. 更新边集合,将与新加入顶点相邻的边加入边集合。

5. 重复步骤3和步骤4,直到最小生成树集合中的顶点数达到了图中顶点数为止。

这些是求解最小生成树的两种常用算法,你可以根据具体情况选择使用其中一种来实现。

1

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

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

最⼩⽣成树---普⾥姆算法(Prim算法)和克鲁斯卡尔算法

(Kruskal算法)

最⼩⽣成树的性质:MST性质(假设N=(V,{E})是⼀个连通⽹,U是顶点集V的⼀个⾮空⼦集,如果(u,v)是⼀条具有最⼩权值的边,其中u属于U,v属于V-U,则必定存在⼀颗包含边(u,v)的最⼩⽣成树)

普⾥姆算法(Prim算法)

思路:以点为⽬标构建最⼩⽣成树

1.将初始点顶点u加⼊U中,初始化集合V-U中各顶点到初始顶点u的权值;

2.根据最⼩⽣成树的定义:从n个顶点中,找出 n - 1条连线,使得各边权值最⼩。循环n-1次如下操作:

(1)从数组lowcost[k]中找到vk到集合U的最⼩权值边,并从数组arjvex[k] = j中找到该边在集合U中的顶点下标

(2)打印此边,并将vk加⼊U中。

(3)通过查找邻接矩阵Vk⾏的各个权值,即vk点到V-U中各顶点的权值,与lowcost的对应值进⾏⽐较,若更⼩则更新lowcost,并将k存⼊arjvex数组中

以下图为例

#include<bits/stdc++.h>

using namespace std;

#define MAXVEX 100

#define INF 65535

typedef char VertexType;

typedef int EdgeType;

typedef struct {

VertexType vexs[MAXVEX];

EdgeType arc[MAXVEX][MAXVEX];

int numVertexes, numEdges;

}MGraph;

最小生成树问题例题

最小生成树问题例题

最小生成树问题例题

最小生成树(Minimum Spanning Tree)是图论中的一个经典问题,它是指在一个带权无向图中找到一棵生成树,使得树上所有边的权值之和最小。最小生成树问题在实际生活中有着广泛的应用,比如电力输送、通信网络等领域。

下面我们以一个具体的例子来说明最小生成树问题的求解过程。

假设有一个无向图,图中包含了6个节点(A、B、C、D、E、F)和9条边。每条边都有一个权值,表示连接两个节点的成本。我们的目标是找到一棵最小生成树。

首先,我们可以使用 Prim 算法来求解最小生成树。Prim 算法的基本思想是从一个起始节点开始,逐步扩展生成树,直到包含所有节点为止。具体步骤如下:

1. 选择一个起始节点,将其标记为已访问。

2. 从已访问的节点中,选择一条连接到未访问节点的最短边。

3. 将这条边加入到最小生成树中,并将连接的节点标记为已访问。

4. 重复步骤2和步骤3,直到所有节点都被访问过。

根据上述算法,我们可以依次选取边 AB、CD、BC、EF、DE 来构建最

小生成树。最终的最小生成树是:A-B、C-D、B-C、E-F 和 D-E 这五条边,它们的权值之和为12。

另外一个常用的求解最小生成树问题的算法是 Kruskal 算法。Kruskal 算法的基本思想是将图中的边按照权值从小到大进行排序,然后依次选取边,如果这条边连接的两个节点不在同一个连通分量中,就将这条边加入到最小生成树中。具体步骤如下:

1. 对图中的边按照权值进行排序。

2. 从权值最小的边开始,依次选取边。

3. 如果选取的边连接的两个节点不在同一个连通分量中,就将这条

最小生成树的优势和好处

最小生成树的优势和好处

最小生成树的优势和好处

最小生成树是一种用于解决连通图最短路问题的算法。它可以帮助我们找到连接一个连通图中所有点的最小边权总和的子图。最小生成树的优势和好处如下:

1. 算法简单易实现

最小生成树的算法思想简单明了,易于理解和实现。基本上任何人都可以通过几行代码来实现它。这样做使得最小生成树成为了一个非常实用的算法,它被广泛应用于实际生活中各种各样的问题中。

2. 计算效率高

最小生成树算法有很好的计算效率。它可以处理大规模的数据集,而不会因为数据集过大而降低计算速度。这使得我们可以在较短的时间内得到一个最小生成树,从而对一些实际问题提供有效的解决方案。

3. 可以帮助我们优化路线

使用最小生成树算法可以帮助我们优化路线。对于一组给定的点,我们可以先用最小生成树算法找出它们之间最短的路径,然后再根据需要设定一些条件来进一步优化这条路径。这样做可以大大提高我们在实际生活中旅游、交通等方面的效率。

4. 减少成本

最小生成树也可以用于减少成本。它可以帮助我们找到一组连接点的最小边权总和,从而使我们在完成任务时尽可能的节省时间和成本。例如,在通信网络的建设中,使用最小生成树算法可以有效地降低网络建设的成本。

5. 能帮助我们更好地理解图论

最小生成树算法是图论中的重要算法。通过学习最小生成树算法,我们能够更好地理解图论的基础知识和主流算法。这将有助于我们更深入地学习并掌握相关的技术和数据结构。

最小生成树

最小生成树

现以图6.12中(a)图为例说明此算法。 设此图是用边集数组表示的,边集数组是
一个结构数组,数组中的每个元素表示一 条边,组成每条边的是三元组序列(边的 起始顶点、边的终止顶点、边的权值)。 将每条边的数据输入之后,按权值的大小 进行了排序,如图6.12(b) 所示。这样,按 权值由小到大选取各边就是在数组中按下 标由1到e(图中边的数目)的次序选取。

{

lowcost[j]=c[k][j];

closest[j]=k;

} }
}

算法分析
该算法中每一步执行都要扫描数பைடு நூலகம்lowcost, 在V-U顶点集中找出与U最近的顶点,令其 为k,并打印边(k,closest[k])。
然后将k加入U顶点集合中,并修改数组 lowcost和closest。

如此进行下去,到所有的顶点均已属于一个 集合时,此最小生成树就构成了。
用一个set[ ]数组来表示顶点,set的初值为 s[i]=0(i=1,2,…,n),表示各顶点自成一个分量。 当从边集数组中按次序选取一条边时,查找 它的两个顶点所属的分量,当这两个分量不 相等,则表明所选的这条边的两个顶点分属 不同的集合,该边加入到生成树中不会形成 环路,应作为生成树的一条边,同时合并这 两个分量为一个连通分量。若这两个分量相 等,则表明这条边的两个顶点同属一个集合, 将此边加入到生成树必产生环路,应予放弃。

最小生成树

最小生成树



#include <iostream> #define max 101 #define inf 10000000 using namespace std; int n=0; int g[max][max]; int prim(int g[][max],int n) //最小生成树PRIM算法 { int lowcost[max]; //LOWCOST[]存储当前集合U分别到剩余结点的最短路径





int main() { int i, j, n, k;int tmp; while (scanf("%d", &n) != EOF) { k = 0;sum=0; for (i = 0; i < n; i++) { Make_Set(i); for (j = 0; j < n; j++) /* 只读取上三角 */ { if (i < j) { e[k].x = i; e[k].y = j; scanf("%d", &e[k].w); k++; } else scanf("%d", &tmp); } } qsort(e, k, sizeof(edge), cmp); for (i = 0; i < k; i++) { Union(Find_Set(e[i].x), Find_Set(e[i].y), e[i].w); } printf("%d\n", sum); } return 0; }

最小生成树

最小生成树

T1
u
顶 点 集 U
u'
T2 v
顶 点 集 V-U
13
应用举例——最小生成树
Prim算法
34 B 12
A 19
26 E
F
46 25
25 38
C
D
17
U={A}
V-U={B, C, D, E, F}
cost={(A, B)34, (A, C)46, (A, D)∞, (A, E)∞, (A, F)19}
Kruskal 算法过程
8
b
c
7
4
a
11
2 i
4
7
6
8
h
g
1
2
两点属于 同一颗树
两点属于 同一颗树
两点属于同 一颗树
d
9
14
e
10 f
当森林只剩下一 棵树时,算法结

#include<iostream> #include<algorithm> using namespace std; struct Edge {
return 1; } void kruskal() {
for(int i=0;i<n;i++)//初始化,将各顶点的父节点标记为本身
root[i]=i; sort(edge,edge+m,cmp);//将所有边 根据边的权值 从小到大排列

数据结构:第7章 图3-最小生成树

数据结构:第7章 图3-最小生成树

lowcost[i] 0 5 0 2 5 0
4
1
6
1 25 3 2
54
5
6
4 1
6
25 3
1 32
4
5
6
(e) u={1,3,6,4} w={2,5} (f) u={1,3,6,4,2} w={5}
i
1234 5 6
closest[i] 1 3 1 6 3 3
lowcost[i] 0 5 0 0 5 0
1 25
3
54
5
6
(c ) u={1,3} w={2,4,5,6}
1
1
4
25
6
32
54
5
6
(d) u={1,3,6} w={2,4,5}
wk.baidu.com
i
1234 5 6
closest[i] 1 3 1 1 3 3
lowcost[i] 0 5 0 5 5 4
i
1234 5 6
closest[i] 1 3 1 6 3 3
生成森林可以利用非连通图的深度优先搜 索遍历或非连通图的广度优先搜索遍历算 法得到。
例2:画出下图的生成森林(或极小连通子图)
A
B
CDE
这是一个无向非连通图 (参见教材P170-171例)
F
GH

最小生成树的方法

最小生成树的方法

最小生成树的方法

最小生成树(Minimum Spanning Tree)是指在一个带权无向连通图中,找到一个包含所有顶点且总权值最小的树。常用的方法有以下几种:

1. Prim算法(普里姆算法):从一个起始顶点开始,逐步扩展生成树,每次选择一个与当前生成树距离最小的顶点加入,直到所有顶点都被包含在生成树中。

2. Kruskal算法(克鲁斯卡尔算法):首先将图的所有边按照权值从小到大排序,然后依次选择权值最小的边加入生成树中,但要保证加入边后不会形成环,直到生成树中包含所有顶点,或者图中的所有边都被考虑过。

3. Boruvka算法(博鲁卡尔算法):将图的所有顶点分成多个不相交的集合,每个集合中的顶点组成一棵生成树,然后每次选择具有最小权值且连接两个不同集合的边加入生成树中,直到只剩下一个集合。

4. Jarnik算法(加尔尼克算法):也称为更改版的Prim算法,首先选择一个起始顶点加入生成树中,然后通过比较当前生成树中的顶点到其他顶点的距离,选择一个距离最小的顶点加入生成树,重复该过程直到所有顶点都被包含在生成树中。

这些方法都可以得到最小生成树,但在某些情况下,它们的效率和性能可能会不同。选择合适的方法取决于具体的应用场景和图的特征。

伪代码描述算法

伪代码描述算法

伪代码描述算法

算法标题:最小生成树(Prim算法)

在图论中,最小生成树是指在一个连通图中找出一棵包含所有顶点且权值最小的树。Prim算法是一种常用的解决最小生成树问题的算法。

1. 算法思想

Prim算法的核心思想是以一个顶点为起点,逐步扩展生成最小生成树。具体步骤如下:

- 首先选取一个起始顶点,将其加入最小生成树的集合中。

- 然后,从与起始顶点相连的边中选择一条权值最小的边,并加入最小生成树的集合中。

- 接着,从已选取的边所连接的顶点中,选择一条权值最小的边,并加入最小生成树的集合中。

- 重复上述步骤,直到最小生成树的集合包含了所有顶点。

2. 算法实现

下面通过伪代码来描述Prim算法的实现过程:

```

Prim(G, s):

初始化集合V为图G的所有顶点

初始化集合S为空,用于存放最小生成树的顶点集合

初始化集合E为空,用于存放最小生成树的边集合

将起始顶点s加入集合S中

重复以下步骤,直到集合S包含了所有顶点:

从集合V-S中选择一条连接到集合S中的顶点的权值最小的边(u, v)

将顶点v加入集合S中

将边(u, v)加入集合E中

返回最小生成树的边集合E

```

3. 算法示例

下面通过一个示例图来演示Prim算法的具体执行过程。

```

输入:图G(V, E),其中V为顶点集合,E为边集合

输出:最小生成树的边集合E

1. 初始化集合V为{A, B, C, D, E, F, G, H}

初始化集合S为空,用于存放最小生成树的顶点集合

初始化集合E为空,用于存放最小生成树的边集合

2. 将起始顶点A加入集合S中

3. 重复以下步骤,直到集合S包含了所有顶点:

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

即最小k+1度限制生成树属于最小k度限制生成树的邻集。

假设我们已经得到了最小p度限制生成树, 如何通过它来求最小p+1度限制生成树呢?
Байду номын сангаас
如图,假设我们 已经得到了v0度为 2时的最小生成树, 现在要求v0度为3 时的最小生成树。 V0
枚举与V0关联且 不在树上的边, 添加到树上。
为了使V0的度增 加,下面两条边 红色的边是不能 删除的。

还是应当掌握度限制生成树的正规算法
最小度限制生成树的定义

设G=(V,E,ω)是连通的无向图,v0 ∈V是特别 指定的一个顶点 , k为给定的一个正整数。 V0在T中的度为DT(v0)。
如果T是G的一个生成树且DT(v0) =k,则称T 为G的k度限制生成树。G中权值和最小的k 度限制生成树称为G的最小k度限制生成树。

Prim:从任一节点出发,不断扩展
– – – –
例题1: POJ 2349 Arctic Network




某地区共有n座村庄,每座村庄的坐标用一对整数 (x, y)表示,现在要在村庄之间建立通讯网络。 通讯工具有两种,分别是需要铺设的普通线路和无 线通讯的卫星设备。 只能给k个村庄配备卫星设备,拥有卫星设备的村 庄互相间直接通讯。 铺设了线路的村庄之间也可以通讯。但是由于技术 原因,两个村庄之间线路长度最多不能超过 d, 否则 就会由于信号衰减导致通讯不可靠。要想增大 d 值, 则会导致要投入更多的设备(成本)
算法:Kruskal 和 Prim

Kruskal:将所有边从小到大加入,在此过程中 判断是否构成回路
– – –
使用数据结构:并查集 时间复杂度:O(ElogE) 适用于稀疏图 使用数据结构:堆 时间复杂度:O(ElogV) 或 O(VlogV+E)(斐波那契堆) 适用于密集图 若不用堆则时间复杂度为O(V2)
首先从V中任取一个顶点(假定取v1),将它并入 U中,此时U={v1},然后只要U是V的真子集(U∈V), 就从那些一个端点已在T中,另一个端点仍在T外 的所有边中,找一条最短边,设为(vi,vj),其中 vi∈U,vj ∈V-U,并把该边(vi, vj)和顶点vj分别并入T 的边集TE和顶点集U,如此进行下去,每次往生成 树里并入一个顶点和一条边,直到n-1次后得到最 小生成树。
动态规划

Best(v)的状态转移方程为 Best(v)=max(Best(Father(v)),w(Father(v),v)) 边界条件为 Best[v0]=-∞,{Best[v’]=-∞|(v0,v’)∈E(T)}。


动态规划

状态总共|V|个,而状态转移的时间复杂度 为O(1),因而总的时间复杂度是O(V),即通过 最小p度限制生成树求最小p+1度限制生成 树的时间复杂度是O(V)。
例题1: POJ 2349 Arctic Network



已知所有村庄的坐标 ( x , y ) ,卫星设备的 数量 k 。 问:如何分配卫星设备,才能使各个村庄 之间能直接或间接的通讯,并且 d 的值最 小?求出 d 的最小值。 数据规模:0 <= k <= n<= 500
(From Waterloo University 2002)


Kruskal算法

假设G=(V,E)是一个具有n个顶点的连通网, T=(U,TE)是G的最小生成树,U=V,TE初值为 空。
将图G中的边按权值从小到大依次选取,若 选取的边使生成树不形成回路,则把它并 入TE中,若形成回路则将其舍弃,直到TE 中包含N-1条边为止,此时T为最小生成树。

关键问题
例题2:POJ 1639 Picnic Planning
这是在一个特殊点V0所连边数有限制(不大于K)条件 下求最小生成树的问题。


最土解法: 枚举去掉V0的一些边,使得V0的度变为K 的方案数,对每种方案求一个最小生成树,然后在 所有的最小生成树里再取最小的。 复杂度极高,但是本题数据弱,可以过。
删去边的权值越 大,所得到的生 成树的权值和就 越小,因此,需 要找到环上可删 除的权值最大的 边并将其删除。
简单的枚举,时 间复杂度非常高。
应该使用动态 规划!
动态规划



设最小p度限制生成树为T , T是无根树,为 了简便,我们把v0作为该树的根。 定义Father(v)为T中v的父结点,Father(v0) 无意义。 设Best(v)为路径v0->v上与v0无关联且权值 最大的边。
1)我们可以先删去v0,对各个连通分量求 最小生成树。
具体实现:枚举每个顶点作为起点执行Prim算 法,执行的过程中对同一连通支的顶点用相同 数字标记。

2)再在每个连通分量中找最小边和v0相连。 3)得到最小m度限制生成树。

时间复杂度分析

求最小m度生成树:O(VlogV+E);

最多k次从p度到p+1度的递推:k*O(V);

概念

T 为 图 G 的 一 个 生 成 树 , a,b 是 G 的 边 , T+a-b记作(+a,-b),如果T+a-b仍然是一 个生成树,则称(+a,-b)是T的一个可行 交换。

T为图G的一个生成树,由T进行一次可行 交换得到的新的生成树所组成的集合, 称为T的邻集,记为N(T)。
定理

总复杂度:O(VlogV+E+kV);

例题3:还是通讯网络




某地区共有n座村庄,每座村庄的坐标用一 对整数(x, y)表示,现在要在村庄之间建立通 讯网络。 通讯工具有两种,分别是需要铺设的普通 线路和卫星设备。 只能给k个村庄配备卫星设备,拥有卫星设 备的村庄互相间直接通讯。 铺设了线路的村庄之间也可以通讯。
定理:设T是图G的最小k度限制树,E0是G中与v0有关联 的边的集合, E1=E0\E(T), E1即是和V0相连,但是不在T中的边的集合 E2=E(T)\E0, E2即是T中不和V0相连的边的集合 A={(+a,-b)| a∈E1,b∈E2}
设ω(a’)-ω(b’)=min{ω(a)-ω(b)| (+a,-b)∈A},则T + a’-b’是G 的一个最小k+1度限制生成树。
思路


假设 d 已知,把所有铺设线路的村庄连接 起来,构成一个图。需要卫星设备的台数 就是图的连通支的个数。 d越小,连通支就可能越多。 那么,只需找到一个最小的d,使得连通支 的个数小于等于卫星设备的数目。
结论

一个图的两棵最小生成树,边的权值序列 排序后结果相同
把一个连通无向图的生成树边按权值递增排序,称排好序的边权列表为有序边权列表,则任意两棵 最小生成树的有序边权列表是相同的。(算法导论23.1-8)
具体实现:从V0开始做一遍广搜即可。 问题:最先求几度的最小度限制生成树呢? 即p从多少开始求?

答案

因为求最小k度限制生成树,当 k < DG(v0) 时,问题并不总是有解的。如图。
V0

所以如果将v0去掉,图会被分成m个连通支, 那么就先求最小m度限制生成树。
如何求最小m度限制生成树

答案

只需先求最小生成树,d 的最小值即为第 k 长边!
例题2:POJ 1639 Picnic Planning
矮人虽小却喜欢乘坐巨大的轿车,车大到可以装下 无论多少矮人。某天,N(N≤20)个矮人打算到野外 聚餐。为了集中到聚餐地点,矮人A 要么开车到 矮人B 家中,留下自己的轿车在矮人B 家,然后乘 坐B 的轿车同行;要么直接开车到聚餐地点,并 将车停放在聚餐地。虽然矮人的家很大,可以停 放无数量轿车,但是聚餐地点却最多只能停放K 辆轿车。给你一张加权无向图,描述了N 个矮人 的家和聚餐地点,求出所有矮人开车最短总路程。
最小生成树


对于一个连通网(连通带权图,假定每条 边上的权均为大于零的实数)来说,每棵 树的权(即树中所有边的权值总和)也可 能不同 具有权最小的生成树称为最小生成树。
最小生成树

生成树


无向连通图的边的集合 无回路 连接所有的点 所有边的权值之和最小

最小

Prim算法

假设G=(V,E)是一个具有n个顶点的连通网, T=(U,TE)是G的最小生成树,U,TE初值均为空集。


如何判断欲加入的一条边是否与生成树 中边构成回路。 将各顶点划分为所属集合的方法来解决, 每个集合的表示一个无回路的子集。开 始时边集为空,N个顶点分属N个集合, 每个集合只有一个顶点,表示顶点之间 互不连通。 当从边集中按顺序选取一条边时,若它 的两个端点分属于不同的集合,则表明 此边连通了两个不同的部分,因每个部 分连通无回路,故连通后仍不会产生回 路,此边保留,同时把相应两个集合合 并
例题4:POJ1679 The Unique MST
题目:要求判断给定图的最小生成树是否唯一
解:显然,这是一个求次小生成树的问题, 如果求出来的次小生成树权值和与最小生 成树相同,则不唯一
次小生成树的定义

设G=(V , E , ω)是连通的无向图,T是图G的 一个最小生成树。如果有另一棵树T1,满 足不存在树T’ , T’ ≠ T , ω(T’)<ω(T1) , 则称T1是图G的次小生成树。
例题3:还是通讯网络


问:怎样合理的分配卫星和铺设线路,使 得在保证每两座村庄之间都可以直接或间 接地通讯的前提下,铺设线路的总长度最 短。? 数据规模:0 <= k <= n <= 500
分析



我们增加一个节点:卫星。卫星到所有节 点的权值都是 0 。 那么,我们要求的仍是一个最小生成树。 只不过卫星最多只能与 k 个节点相连。 也就是说,节点:卫星的度限制为 k 。 这是一个最小度限制生成树的问题!

图例
关键问题

每次如何从连接T中和T外顶点的所有边中,找 到一条最短的 1) 如果用邻接矩阵存放图,而且选取最短边的 时候遍历所有边进行选取,则时间复杂度为 O(V2), V 为顶点个数 2)用邻接表存放图,并使用堆来选取最短边,则 时间复杂度为O(ElogV) 不加堆的Prim 算法适用于密集图,加堆的适用 于稀疏图
具体操作
最小生成树(MST)问题
by yzc
图的生成树


在一个连通图G中,如果取它的全部顶点和 一部分边构成一个子图G’,即: V(G’)=V(G);E(G’) ∈E(G) 若边集E(G’)中的边既将图中的所有顶点连 通又不形成回路,则称子图G’是原图G的一 棵生成树。 一棵含有n个点的生成树,必含有n-1条边。
证:设最小生成树有n条边,任意两棵最小生成树分别称为A, B, 如果e是一条边,用w(e)表示该边 的权值。 A的边按权值递增排序后为a1, a2,……an w(a1)≤w(a2)≤……w(an) B的边按权值递增排序后为b1, b2,……bn w(b1)≤w(b2)≤……w(bn) 设i是两个边列表中,第一次出现不同边的位置,ai≠bi 不妨设w(ai)≥w(bi) 情形1 如果树A中包含边bi,则一定有j>i使得 bi=aj ,事实上,这时有 w(bi)=w(aj)≥w(ai) ≥w(bi) 故 w(bi)=w(aj)=w(ai),在树A的边列表中交换边ai和 aj的位置并不会影响树A的边权有序 列表,两棵树在第i个位置的边变成同一条边。 情形2 树A中并不包含边bi,则把bi加到树A上,形成一个圈,由于A是最小生成树,这个圈里任意 一条边的权值都不大于w(bi) ,另外,这个圈里存在边aj不在树B中。因此,有w(aj)≤w(bi),且 j>i (因为aj不在B中)。于是,有w(bi)≤w(ai)≤w(aj)≤w(bi),因此 w(ai)= w(aj) = w(bi)。那么在树A中把aj换成bi仍然保持它是一棵最小生成树,并不会影响树A的 边权有序列表,并且转换成情形1。
次小生成树有可能也是最小生成树

定理
定理:次小生成树属于最小生成树的邻集。 即次小生成树可以通过由最小生成树换一条 边来得到。

结论


另一个结论: T是某一棵最小生成树,T0是任一棵异于T 的树,则定可通过变换 T0 --> T1 --> T2 --> ... --> Tn (T) 变成最小生成树。 所谓的变换是,每次把Ti中的某条边换成T 中的一条边, 而且树T(i+1)的权小于等于Ti的 权。
相关文档
最新文档