最小生成树

次小生成树

半城伤御伤魂 提交于 2020-01-22 03:01:18
The Unique MST (题目传送门) Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V’, E’), with the following properties: 1. V’ = V. 2. T is connected and acyclic. Definition 2 (Minimum Spanning Tree): Consider an edge-weighted, connected, undirected graph G = (V, E). The minimum spanning tree T = (V, E’) of G is the spanning tree that has the smallest total cost. The total cost of T means the sum of the weights on all the edges in E’. Input

Jungle Roads 最小生成树

我怕爱的太早我们不能终老 提交于 2020-01-21 02:07:27
Jungle Roads 原题链接https://vjudge.net/contest/352170#problem/A 也算是最小生成树的板子,对于题目给的数据要进行读取,将ABCDE转化为我们常用的12345,题目中已经将所有的路都给出来了,我们只需要读取然后使用最小生成树计算即可。 Prim: # include <algorithm> # include <cmath> # include <cstdio> # include <cstdlib> # include <cstring> # include <iostream> # include <queue> # include <stack> using namespace std ; const int INF = 0x3f3f3f3f ; //标记最大值 long long map [ 105 ] [ 105 ] ; //记录所有情况 long long ans ; long long n ; bool vis [ 30005 ] ; //是否使用 long long dis [ 300005 ] ; //距离 void prim ( ) { ans = 0 ; long long i , j ; for ( i = 1 ; i <= n ; i ++ ) { dis [ i ] = map [ 1 ] [ i ]

Minimum Spanning Tree - Prim and Kruskal

耗尽温柔 提交于 2020-01-19 04:01:17
两种算法都是基于 贪心思想 实现的。 Kruskal算法 初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最小生成树的边集合里,直到所有顶点都在一颗树内或者有n-1条边为止。 生成过程 Prim算法 每次迭代选择代价最小的边对应的点,加入到最小生成树中。算法从某一个顶点s开始,逐渐长大覆盖整个连通网的所有顶点,直到最小生成树有n-1条边或者n个顶点为止。 生成过程 来源: CSDN 作者: lizhongV 链接: https://blog.csdn.net/qq_33904395/article/details/103797687

Kruskal最小生成树及应用

£可爱£侵袭症+ 提交于 2020-01-19 00:05:05
生成树: 已知连通图G,图上有n个顶点。 生成树是指图G的一个极小(边最少)连通子图,生成树上有n个顶点,n-1条边,且任意两点之间都是联通的。 最小生成树: 已知带权连通图G,图中有n个顶点,每条边都有权值。 要从图中抽出一棵生成树,使得树上所有边权之和最小,这棵树就叫做最小生成树(Mininum Spanning Tree,MST)。 常见解法有Kruskal算法和Prim算法。 Kruskal算法: 定义带权无向图G的边集合为E,再定义最小生成树的边集合为T,初始集合T=空。 1.首先把图G看成一个有n棵树的森林,图上每个顶点对应一棵树; 2.然后把边集E的每条边,按照权值从小到大进行排序; 3.按边权从小到大的顺序遍历每条边e=(u,v),我们记顶点u所在的树为T u ,顶点v所在的树为T v ,如果T u 和T v 不是同一棵树,则我们将边e加入集合T,并将两棵树Tu和Tv进行合并;否则不进行任何操作。 算法执行完毕后,如果集合T包含n-1条边,则T就代表最小生成树中的所有边。 第三步操作需要对集合进行合并操作,因此要用并查集来维护。 算法复杂度:若使用快排则复杂度为O(ElogE),总时间复杂度为O(ElogE+Vα(V)),其中α(V)可近似被当作常数。 带详细解释の模板: #include <iostream> #include <cstdio> #include

The Unique MST(最小生成树的唯一性判断)

回眸只為那壹抹淺笑 提交于 2020-01-18 03:01:00
Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V', E'), with the following properties: 1. V' = V. 2. T is connected and acyclic. Definition 2 (Minimum Spanning Tree): Consider an edge-weighted, connected, undirected graph G = (V, E). The minimum spanning tree T = (V, E') of G is the spanning tree that has the smallest total cost. The total cost of T means the sum of the weights on all the edges in E'. Input The first line contains

Qin Shi Huang's National Road System HDU - 4081(生成树问题)

笑着哭i 提交于 2020-01-17 16:19:03
题目链接 大意:给出N个点的坐标以及每个点的人口, 要求将这N个点通过N-1条边连接起来, 权值为两点直接距离, B为距离和, 同时可以选中一条边, 使得该边权值变为0, A为该边两点人口数量. 求A/B的最大值。 思路: 为了使的A/B值最大,首先是需要是B尽量要小,所以可先求出n个城市的最小生成树。然后,就是决定要选择那一条用徐福的魔法来变。 因此,可以枚举每一条边,假设最小生成树的值是MinMST, 而枚举的那条边长度是w[i][j], 如果这一条边已经是属于最小生成树上的,那么最终式子的值是A/(MinMST-w[i][j])。如果这一条不属于最小生成树上的, 那么添加上这条边,就会有n条边,那么就会使得有了一个环,为了使得它还是一个生成树,就要删掉环上的一棵树。 为了让生成树尽量少,那么就要删掉除了加入的那条边以外,权值最大的那条路径。 假设删除的那个边的权值是path[i][j],那么就是A/(MinMST-path[i][j])。 可以看到, 虽然这里没有直接使用次小生成树, 但是完全用到了次小生成树求出的几个数组, 这也是前面为何没有直接求出次小生成树的原因, 因为大部分的题目必然不是裸题, 所以更要仔细理解次小生成树的思想。 这题两种Kruskal和Prim都可以用。我都用了,因为我还没学过Prim,蒟蒻哭泣。 Kruskal代码 # include

普利姆算法解决最小生成树问题

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-17 02:58:39
普利姆算法就是从第一个顶点出发,每次都选择已访问节点的最短相邻节点,最后将所有节点都访问,代码: /** * 普利姆算法解决最小生成树问题 */ public class PrimAlgorithm { public static void main(String[] args) { char[] data = {'A','B','C','D','E','F','G'}; int verx = data.length; //二维数组表示邻接矩阵,10000表示两点不连通 int[][] weight = { {10000,5,7,10000,10000,10000,2}, {5,10000,10000,9,10000,10000,3}, {7,10000,10000,10000,8,10000,10000}, {10000,9,10000,10000,10000,4,10000}, {10000,10000,8,10000,10000,5,4}, {10000,10000,10000,4,5,10000,6}, {2,3,10000,10000,4,6,10000} }; MGraph mGraph = new MGraph(verx); MinTree minTree = new MinTree(); minTree.createMGraph(mGraph,verx,data

Prim最小生成树算法

别来无恙 提交于 2020-01-16 14:51:35
在一个具有几个顶点的连通图G中,如果存在子图G'包含G中所有顶点和一部分边,且不形成回路,则称G'为图G的生成树,代价最小生成树则称为最小生成树。 许多应用问题都是一个求无向连通图的最小生成树问题。例如:要在n个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同;另一个目标是要使铺设光缆的总费用最低。这就需要找到带权的最小生成树。 性质 最小生成树的边数必然是顶点数减一,|E| = |V| - 1。 最小生成树不可以有循环。 最小生成树不必是唯一的。 Prim算法 与 Kruskal算法 是寻找最小生成树的经典方法。 prim算法: 从单一顶点开始,普里姆算法按照以下步骤逐步扩大树中所含顶点的数目,直到遍及连通图的所有顶点。 输入:一个加权连通图,其中顶点集合为V,边集合为E; 初始化:V new = {x},其中x为集合V中的任一节点(起始点),E new = {}; 重复下列操作,直到V new = V: 在集合E中选取权值最小的边(u, v),其中u为集合V new 中的元素,而v则不是(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一); 将v加入集合V new 中,将(u, v)加入集合E new 中; 输出:使用集合V new 和E new 来描述所得到的最小生成树。

最小生成树-Prim算法和Kruskal算法

*爱你&永不变心* 提交于 2020-01-16 14:36:26
Prim算法 1.概览 普里姆算法 ( Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有 顶点 ( 英语 : Vertex (graph theory)),且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家 沃伊捷赫·亚尔尼克 ( 英语 : Vojtěch Jarník)发现;并在1957年由美国计算机科学家 罗伯特·普里姆 ( 英语 : Robert C. Prim)独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法。 2.算法简单描述 1).输入:一个加权连通图,其中顶点集合为V,边集合为E; 2).初始化:V new = {x},其中x为集合V中的任一节点(起始点),E new = {},为空; 3).重复下列操作,直到V new = V: a.在集合E中选取权值最小的边<u, v>,其中u为集合V new 中的元素,而v不在V new 集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一); b.将v加入集合V new 中,将<u, v>边加入集合E new 中; 4).输出:使用集合V new 和E new 来描述所得到的最小生成树。 下面对算法的图例描述

CCPC-Wannafly-day3

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-14 23:38:27
今天是CCPC训练营的第三天,今天讲的是图论,首先讲了下图的基本术语,发现有好几个以前都没听过(知识点太浅薄了)。然后讲了最小生成树,但老师讲的最小最小生成树不是死模板,进行了一些操作使时间复杂度更小了。然后还讲了拓扑排序,匹配和强连通,这些还好,可以跟上。然后就是带负边的图了,还讲了好多都没听过的一些算法,然后就是一脸懵逼的听着,感觉那个算法很牛逼,但听不怎么懂的那种。 emmmmm,下午又是长达五个小时的比赛。题目难度感觉比区域赛还难(菜是原罪),刷出了两个题就刷不动了,图论题一点思路都没有,其他题好像更难,然后剩下的四个小时都在煎熬都度过。从上午的一些听不懂,到看到下午测试的题,感觉又要自闭了。ε=(´ο`*)))唉,已经连续三次比赛是两个题了………目标:后天一定要刷三个(hhhhhh)。 知道的知识点太少了,晚上讲题时,发现那些题用的算法很多都没学过。 来源: https://www.cnblogs.com/zcb123456789/p/12194316.html