次小生成树(Prim + Kruaskal)】的更多相关文章

问题引入: 我们先来回想一下生成树是如何定义的,生成树就是用n - 1条边将图中的所有n个顶点都连通为一个连通分量,这样的边连成子树称为生成树. 最小生成树很明显就是生成树中权值最小的生成树,那么我们即将要学的次小生成树或者K小生成树是怎么定义的呢,很明显就是生成树中权值第k小的生成树. 下面给出刘老师书中对次小生成树的定义,我是用自己的话描述的. 对于一个无向图G(V, E),其定义了边权为W(u, v),若T为他的一颗最小生成树,那么我们假设存在一颗生成树T1,不存在任意一颗G的生成树T2满…
思路: Prim: 这道题目中有重边 Prim可以先加一个sec数组来保存重边的次小边,这样不会影响到最小生成树,在算次小生成树时要同时判断次小边(不需判断是否在MST中) Kruskal: Kruskal对重边就很友好了,不用考虑 原理是这样的:我们先找最小生成树并用used标记好哪些边是MST的边,然后我们暴力遍历每一条MST边被删去的情况,如果还能生成MST就找出这些MST最小的,这棵MST就是次小生成树 Prim代码: #include<cmath> #include<stack…
求次小生成树思路: 先把最小生成树求出来  用一个Max[i][j] 数组把  i点到j 点的道路中 权值最大的那个记录下来 used数组记录该条边有没有被最小生成树使用过   把没有使用过的一条边加入最小生成树必然回形成一条回路   在这条回路中减去 除加入的边的权值最大的一条边  原图必然保持连通  (如果此时 权值最大的边和新加入的边权值相同  则存在 不同的最小生成树) 把每一条边加入再删除后 即可得出次小生成树 参考了: https://blog.csdn.net/qq_3395144…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4081 题意:有n个城市,秦始皇要修用n-1条路把它们连起来,要求从任一点出发,都可以到达其它的任意点.秦始皇希望这所有n-1条路长度之和最短.然后徐福突然有冒出来,说是他有魔法,可以不用人力.财力就变出其中任意一条路出来. 秦始皇希望徐福能把要修的n-1条路中最长的那条变出来,但是徐福希望能把要求的人力数量最多的那条变出来.对于每条路所需要的人力,是指这条路连接的两个城市的人数之和. 最终,秦始皇给…
Qin Shi Huang's National Road System HDOJ-4081 本题考查的是次小生成树的问题,这里的解决方法就是先使用Prim算法求解最小生成树. 在求解最小生成树的时候通过一个数组记录每一对顶点之间的路径上长度最长的一条边.这个由一个cost数组记录. 最后,再依次遍历每一对顶点,如果这对顶点不在最小生成树里面,则直接去掉这条边改成魔法边.否则就将这对顶点之间的那条路径上面最长的一条边去掉,用i,j这对顶点代替. #include<iostream> #incl…
水题... 题目大意: 用一个7位的字符串代表一个编号,两个编号之间的distance代表这两个编号之间不同字母的个数.一个编号只能由另一个编号“衍生”出来,代价是这两个编号之间相应的distance,现在要找出一个“衍生”方案,使得总代价最小,也就是distance之和最小. 很容易想到,将每两个顶点间的distance求出作为边权,将题目转化为最小生成树问题.由于是稠密图,所以用prim算法. 代码: #include<iostream> #include<cstdio> #i…
题目链接: https://vjudge.net/problem/ZOJ-1586 题目大意: 首先给一个t,代表t个测试样例,再给一个n,表示有n个QS装置,接下来一行是n个QS装置的成本.接下来是n*n的矩阵,表示每两个QS 装置之间链接需要的费用.求在全联通的情况下求最少费用. 思路: 这里需要求最少费用,由于点和边都有权值,索性直接把两端点的权值加到边的权值上,那就变成了一个裸的MST题目了 #include<iostream> #include<cstdio> #incl…
题目链接: https://vjudge.net/problem/POJ-1789 题目大意: 用一个7位的string代表一个编号,两个编号之间的distance代表这两个编号之间不同字母的个数.一个编号只能由另一个编号"衍生"出来,代价是这两个编号之间相应的distance,现在要找出一个"衍生"方案,使得总代价最小,也就是distance之和最小. 思路: 最小生成树模板题,这里是稠密图,应该用prim算法 直接在原来模板的基础上稍加改动即可 #include…
#include <iostream> #include <cstring> #include <cstdio> using namespace std; #define INF 0x3f3f3f3f #define MAXN 105 bool visit[MAXN]; //标记数字是否放入一个集合 int lowc[MAXN]; //维护的最低代价数组 int cost[MAXN][MAXN]; //边的的权值 int Prim(int n){ int ans = 0…
原博客出处:https://blog.csdn.net/yasola/article/details/74276255 通常次小生成树是使用Prim算法进行实现的,因为可以在Prim算法松弛的同时求得最小生成树上任意两点之间的最长边.但是利用Kruskal算法却没办法在松弛的同时求得. 所以我们就要在Kruskal求完最短路后,对于每个顶点bfs一次,得到树上任意两点的最长边.之后求可以像之前一样枚举不在树上的边,代替找最小值了. 两种方法的时间杂度是一样的,但Kruskal的实现代码回长非常多…