最小生成树

图的最小生成树 - Java实现

99封情书 提交于 2019-12-23 04:51:58
图片来自:勿在浮沙筑高台http://blog.csdn.net/luoshixian099/article/details/51908175 一、前言 在了解图的最小生成树之前,先弄清几种图的概念: 连通图 :在无向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该无向图为连通图。 强连通图 :在有向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该有向图为强连通图。 连通网 :在连通图中,若图的边具有一定的意义,每一条边都对应着一个数,称为权;权代表着连接连个顶点的代价,称这种连通图叫做连通网。 生成树 :一个连通图的生成树是指一个连通子图,它含有图中全部n个顶点,但只有足以构成一棵树的n-1条边。一颗有n个顶点的生成树有且仅有n-1条边,如果生成树中再添加一条边,则必定成环。 最小生成树 :在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树。 二、两种最小生成树算法 1.Prim算法 此算法可以称为“加点法”,每次迭代选择代价最小的边对应的点,加入到最小生成树中。算法从某一个顶点s开始,逐渐长大覆盖整个连通网的所有顶点。 步骤: 图的所有顶点集合为V;初始令集合u={s},v=V−u 在两个集合u,v能够组成的边中,选择一条代价最小的边(u0,v0),加入到最小生成树中,并把v0并入到集合u中 重复上述步骤,直到最小生成树有n

【图论】【最小生成树】USACO 3.1 Agri-Net 最短网络 (最小生成树)

不问归期 提交于 2019-12-22 08:13:28
Description 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。每两个农场间的距离不会超过100000 Input 第一行: 农场的个数,N(3<=N<=100)。 第二行…结尾: 后来的行包含了一个N*N的矩阵,表示每个农场之间的距离。理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们限制在80个字符,因此,某些行会紧接着另一些行。当然,对角线将会是0,因为不会有线路从第i个农场到它本身。 Output 只有一个输出,其中包含连接到每个农场的光纤的最小长度。 Sample Input 4 0 4 9 21 4 0 8 17 9 8 0 16 21 17 16 0 Sample Output 28 解题思路 题目:给你一个无向图,求最小生成树 输入:一个无向图 过程:求最小生成树 输出:树边和 (说这么多,其实我想表达这题就是个最小生成树模板) 欢快推荐 prim算法 和 kruskal算法 (你们不想看,我也不想解释) 把prim的注释复制了过来 #include < iostream >

【图论】【最小生成树】

一世执手 提交于 2019-12-22 01:34:18
Description 给出N个点的坐标,对它们建立一个最小生成树,代价就是连接它们的路径的长度,现要求总长度最小。N的值在100以内,坐标值在[-10000,10000].结果保留二位小数 Input 5 ---------------5个点 0 0 ---------------5个点点的坐标 0 1 1 1 1 0 0.5 0.5 Output 2.83 Sample Input Sample Output Source zju 解题思路 这个被老师严重删略题目,真是看得我一脸懵逼。然后我复制模板时,忘记把输入改成实数型。。。 坚强围笑 😐 其实还是一道模板,于是我把 模板 找出来复制上去。但是两点之间的距离要自己求,于是我打开了 baidu ,把公式抄了上去 :) #include < iostream > #include < cstdio > #include < cstring > #include < cmath > using namespace std ; const int INF = 0x7fffffff ; int v [ 200 ] , n ; double Gun , dis [ 200 ] , x [ 200 ] , y [ 200 ] , a [ 200 ] [ 200 ] ; void prim ( ) { //整个过程最好看看我的模板 dis

数据结构之图的应用——求最小生成树的Prim算法

时光怂恿深爱的人放手 提交于 2019-12-21 20:23:27
实验内容 若在n个城市之间建设通信网络,只需要架设n-1条线路即可,如何在最节省经费的前提下建立这个通信网?按普里姆算法编写程序,求最小生成树并输出结果。 在每两个城市之间都可以设置一条线路,n个城市间,最多可设置n(n-1)/2条线路n个城市间建立通信网,只需n-1条线路。 数据结构(C语言版)清华大学出版社 P173 7.4.3 问题转化为: 如何在可能的n(n-1)/2条线路中选择n-1条,能把所有城市(顶点)均连起来,且总耗费最小。 算法分析 最小生成树的MST的性质: 假设N=(V,{E})是一个连通网,U是顶点集V的一个非空子集。若 (u,v)是一条具有最小权值(代价)的边,其中u ∈ U,v∈V-U,则必存在一棵包含边 (u,v)的最小生成树。 本次实验求最小生成树的方法为普里姆算法(Prim),具体思路为: 设N=(V,{E})是连通网(无向网),初始情况:U={u0},(u0V),u0表示最小生成树是从顶点u0出发的; TE是N上最小生成树中边的集合,TE= {},初始状态为空。 在所有uU,vV-U的边(u,v)E中,找一条代价,即权值最小的边(u0,v0) 将(u0,v0)并入集合TE,同时v0并入U。 重复上述操作直至最小生成树是的顶点包括图中所有顶点为止(U=V),则T=(V,{TE})为N的最小生成树 。

Agri-Net 最短网络 (最小生成树) 题解

落花浮王杯 提交于 2019-12-21 13:41:06
Agri-Net 最短网络 (最小生成树) 题目 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。每两个农场间的距离不会超过 100000 100000 1 0 0 0 0 0 输入 第一行: 农场的个数, N N N ( 3 < = N < = 100 ) ( 3<= N <=100 ) ( 3 < = N < = 1 0 0 ) 。 第二行…结尾: 后来的行包含了一个 N ∗ N N*N N ∗ N 的矩阵,表示每个农场之间的距离。理论上,他们是 N N N 行,每行由 N N N 个用空格分隔的数组成,实际上,他们限制在 80 80 8 0 个字符,因此,某些行会紧接着另一些行。当然,对角线将会是 0 0 0 ,因为不会有线路从第 i i i 个农场到它本身。  ` 输出 只有一个输出,其中包含连接到每个农场的光纤的最小长度。 样例 input 4 0 4 9 21 4 0 8 17 9 8 0 16 21 17 16 0 output 28 解题思路 这就是一个板子呀 复制粘贴真开心,嘿嘿

图论总结

你。 提交于 2019-12-17 07:43:55
一、最短路   最短路常见算法包括堆优化Dijkstra、Bellman-Ford、SPFA、Floyd。   Dijkstra的时间复杂度为O(mlongn),但是但是不能处理负边权。   基于“松弛”操作(或称三角形不等式)的Bellman-Ford时间复杂度为O(nm),可以处理负边权。队列优化的Bellman-Ford,即SPFA,时间复杂度降到了O(km)(k通常为一个较小的常数),但是在特殊构造的图(比如网格图)中容易退化,因此有的大佬建议尽量不要在正式比赛中使用SPFA。   SPFA也可用于差分约束系统,将在第十部分讲解。   与前三种基于贪心的单源最短路不同,基于动态规划的Floyd是一种多源最短路算法,还可以用于求传递闭包等,但时间复杂度达到了O(n 3 ),无法处理较大的数据。   考场上一般不会考裸的最短路,次短路和最短路计数估计也不常考。我个人觉得真正可能作为考题出现的是最短路树,即由某一点出发的最短路上的边构成的树。众所周知,树拥有许多优秀的性质,也因此常常作为考点。放上几道题:   WOJ #3771 「一本通 3.1 例 1」黑暗城堡(比较裸的最短路树)   WOJ #2423 安全出行Safe Travel(USACO的题)    WOJ#4709 迷路 (某道校内模拟赛题)   最短路也可以与其它算法结合:   WOJ #3841 双调路径

最小生成树

跟風遠走 提交于 2019-12-17 05:46:17
  这篇博客是关于图论中的最小生成树,在这里我们先简单介绍最小生成树的概念:一个图中,选取总代价最小的边使得所有点都连通。由此得到的结果必然是一棵树,同时需要注意一个图的最小生成树不具有唯一性。下面介绍求最小生成树的一种方法:普里姆算法求最小生成树。   普里姆算法正确性可以使用反证法进行证明,这里不进行展开。   普里姆算法的核心为以下步骤:   (1)使用一个d数组用于存储各个节点到树的距离,初始化d数组为无穷大。使用一个book数组用于区分某个节点是树节点还是非树节点,book数组初始化为false。首先从任意一个顶点开始构造树,按照习惯从第1号节点开始构造树,将d[1] = 0,book[1] = true。   (2)更新与1号节点相连的非树节点到树的距离,也就是更新d数组,更新条件为:如果i节点到树的距离比d[i]中存储的距离小,那么更新d[i]为更小的值。   (3)遍历更新后的d数组,找到非树节点中距离树最小的节点,将这个节点加入树中。   (4)重复步骤1、2、3,直到生成树中有n个节点为止。   下面为实现代码:    #include <iostream> #include <cstdio> using namespace std; const int MAXN = 5001; const int MAXM = 20001; struct Line { int

普利姆算法求最小生成树权值之和

允我心安 提交于 2019-12-15 11:47:00
#include<iostream> #include<string.h> using namespace std; #define Max 50 typedef struct { char data; //顶点的数据 int num;//顶点的数组下标 }VertexType; typedef struct Gnode //建立一个无向图 { int Nv;//顶点数 int Ne;//边数 int G[Max][Max]; //最大max行 max列的矩阵 VertexType vex[Max]; }*Graph,graph; typedef struct ENode { int v1,v2; //有向边v1 v2 int weight; //邻接矩阵里面的值都是两条边之间的权值 }*Ptr,ptr; void init_Graph(Graph &L); void creat_graph(int vertexnum,Graph &L); //所有顶点,一条边都没有 void built_graph(Graph &L,int &e); void insert_Ne(Graph L,Ptr t); void built_graph(Graph &L); void printlist(Graph L); //打印邻接矩阵 void prim(Graph &L,int v0,float

最小生成树Prim算法理解

吃可爱长大的小学妹 提交于 2019-12-15 01:37:03
MST(Minimum Spanning Tree,最小生成树)问题有两种通用的解法,Prim算法就是其中之一,它是从 点的方面 考虑构建一颗MST,大致思想是:设图G顶点集合为U,首先任意选择图G中的一点作为起始点a,将该点加入集合V,再从集合U-V中找到另一点b使得点b到V中任意一点的权值最小,此时将b点也加入集合V;以此类推,现在的集合V={a,b},再从集合U-V中找到另一点c使得点c到V中任意一点的权值最小,此时将c点加入集合V,直至所有顶点全部被加入V,此时就构建出了一颗MST。因为有N个顶点,所以该MST就有N-1条边,每一次向集合V中加入一个点,就意味着找到一条MST的边。 用图示和代码说明: 初始状态: 设置2个数据结构: lowcost[i]:表示以i为终点的边的最小权值,当lowcost[i]=0说明以i为终点的边的最小权值=0,也就是表示i点加入了MST mst[i]:表示对应lowcost[i]的起点,即说明边<mst[i],i>是MST的一条边,当mst[i]=0表示起点i加入MST 我们假设V1是起始点,进行初始化(*代表无限大,即无通路): lowcost[2]=6 , lowcost[3]=1 , lowcost[4]=5 , lowcost[5]=*, lowcost[6]=* mst[2]=1 , mst[3]=1, mst[4]=1 ,

prim(最小生成树模板)

余生颓废 提交于 2019-12-14 17:55:50
描述 使用prim算法求某图的最小生成树的边的权值输出的序列。例如下图的最小生成树的权值输出序列为1 4 2 5 3,要求从V1顶点开始生成最小生成树。 输入 若干行整数 第一行为两个整数,分别为图的顶点数和边数 第二行开始是该图的邻接矩阵,主对角线统一用0表示,无直接路径的两点用100来表示(保证各边权值小于100) 输出 若干用空格隔开的整数 样例输入 6 10 0 6 1 5 100 100 6 0 5 100 3 100 1 5 0 5 6 4 5 100 5 0 100 2 100 3 6 100 0 6 100 100 4 2 6 0 样例输出 1 4 2 5 3 #include<iostream> #include<algorithm> using namespace std; #define INF 0x3f3f3f3f #define ll long long const int N=100000+100; const int M=3e6+1005; int w[2000][2000];//储存边 int dist[2000];//保存到已选集合的最小权值 bool vis[2000];//标记是否已经被选 int main() { int n,m; cin>>n>>m; for(int i=1;i<=n;++i) { for(int j=1;j<=n;++j)