Kruskal重构树详解

这篇具有很好参考价值的文章主要介绍了Kruskal重构树详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

Kruskal算法

Kruskal重构树


在学习重构树之前,我们要先熟悉一下基本的kruskal算法

Kruskal算法

首先给出一张有向图,让我们求最小生成树(用总权值最小的一些边的集合,使得所有点都能互通,很明显n个点会有n-1条边)

Kruskal重构树详解

kruskal算法思想是先把所有的边按权值大小排序,得到这个样子

Kruskal重构树详解

然后从小往大依次取边,如果加上这条边和之前的边构成了环,就舍弃这条边,不然就加上,直至取得n-1条边,构成一棵树

例如此图,我们按照权值加完前四条边

Kruskal重构树详解

在加入第五条边时,我们发现原图出现了环,我们就舍弃这条边

Kruskal重构树详解

就这样一直加边,直至构成一棵完整的树

Kruskal重构树详解

这就是kruskal算法的

Kruskal重构树

那么什么又是kruskal重构树呢?

kruskal重构树其实就是把这张图重建成一个二叉树,原图中所有的叶子节点都为原图中的点

其他点都有一个点权w,代表从左集合到右集合的路径,由于重构树是在kruskal的基础上完成的,所以我们必然可以得到一个自下而上点权不降的二叉树

比如我们还用上图距离,建一颗重构树

首先我们合并6,7两个集合,把他们两个连接到一个虚点上,该点权值为他们的边权

Kruskal重构树详解

(红色代表虚点,白色代表原图的点)

然后我们依次2-8 , 5-6 

Kruskal重构树详解

就这样把这颗二叉树建完

Kruskal重构树详解

最后重构树大概长这样

这棵树有很多独特的性质

就比如我们想知道从节点2到7路径的最大边权是多少,其实就是他们公共祖先这个虚点的点权值

再比如我们想知道从某个点出发,给出一个值,在通过所有边的权值都小于等于这个值时,我们走过多少个点,其实就等于这个点一直往上面找,找到最后一个小于等于这个值的虚点,他的子树的点我们都是可以通过的(因为从上到下点权不上升)

以上这种问题我们都可以通过在重构树上倍增的方式,把时间复杂度压到logn

典型例题有洛谷的P2245 星际导航 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

和去年icpc上海区域赛的H Problem - H - Codeforces

重构树板子:

int n, m;
int k, T, S, D;
struct edge
{
    int a, b, w;
    bool operator <(const edge& ee)const { return w < ee.w; }
}ed[M];
vector<int> e[N];//即为重构树
int d[N];
int p[N];
int a[N];
int down[N];
int fa[N][18];
int find(int x) {
    return p[x] == x ? p[x] : p[x] = find(p[x]);
}
int kruskal() {
    sort(ed + 1, ed + 1 + m);
    fer(i, 1, 2*n)p[i] = i;
    int cnt = n;
    fer(i, 1, m) {
        int a = find(ed[i].a), b = find(ed[i].b);
        if (a^b){
            d[++cnt]=ed[i].w;
            p[a]=p[b]=cnt;
            e[cnt].push_back(a);
            e[cnt].push_back(b);
        }
    }
    return cnt;
}

 文章来源地址https://www.toymoban.com/news/detail-422661.html

 

 

到了这里,关于Kruskal重构树详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 实验13 prim算法和kruskal算法

    🔑一个神奇的哔哩哔哩讲解链接 🔑笔记补充——第十七章:贪婪算法(思想同,但应用上和伪代码略有差别) 使用prim算法实现最小生成树 输入 第一行两个整数n,e。n ( 1 ≤ n ≤ 200000 1 leq n leq 200000 1 ≤ n ≤ 200000 ) 代表图中点的个数,e ( 0 ≤ m ≤ 500000 0 leq m leq 500000 0 ≤

    2024年02月04日
    浏览(30)
  • 最小生成树(Prim算法,Kruskal算法)

    (1)生成树: 如果在一个无向连通图不包含回路(连通图中不存在环),则为一个树 (2)最小生成树(minimal spanning tree): 在一个图所有生成树中,代价最小的生成树称为最小生成树 (3)生成树的代价: 在一个无向连通网中,生成树各边的权值之和称为该生成树的代价

    2024年02月08日
    浏览(27)
  • 最小生成树——Kruskal算法

    目录 基本思想 实现 伪代码 实际问题求解 最小生成树 :带权连通图的生成树中 边的权值之和最小的生成树。 最小生成树不是唯一的。当图中的各边权值互不相等时,最小生成树是唯一的; 若无向连通图本身是一棵树时(边数比顶点数少1 ),则最小生成树就是它本身。 最

    2023年04月26日
    浏览(38)
  • Kruskal 算法 最小生成树

    1.按边从小到大进行排序 2.从小到大进行加边,保证加入的边的两端点不连通,即保证不形成回路

    2024年02月10日
    浏览(31)
  • Kruskal 算法介绍

    构造最小生成树还有一种算法,即 Kruskal 算法:设图 G=(V,E)是无向连通带权图,V={1,2,...n};设最小生成树 T=(V,TE),该树的初始状态只有 n 个节点而无边的非连通图T=(V,{}),Kruskal 算法将这n 个节点看成 n 个孤立的连通分支。它首先将所有边都按权值从小到大排序,然

    2024年02月05日
    浏览(33)
  • Kruskal算法

    前置知识 :并查集、图的存储、贪心思想 为了保证学习效果,请保证已经掌握前置知识之后,再来学习本章节!如果在阅读中遇到困难,也可以回到前面章节查阅。 适用于稀疏图,时间复杂度 O(mlogm)O(mlogm)。 核心思想:从小到大挑不多余的边,属于贪心的算法。 之前介绍

    2024年02月08日
    浏览(22)
  • 【图论】kruskal算法

     Kruskal(克鲁斯卡尔)算法是一种用于解决最小生成树问题的贪心算法。 最小生成树是指在一个连通无向图中,选择一棵包含所有顶点且边权重之和最小的树。 下面是Kruskal算法的基本步骤: 将图中的所有边按照权重从小到大进行 排序 。 创建一个空的最小生成树 集合(并

    2024年02月15日
    浏览(25)
  • 最小生成树—Kruskal算法和Prim算法

    连通图:在无向图中,若从顶点v1到顶点v2有路径,则称顶点v1与顶点v2是连通的。如果图中任 意一对顶点都是连通的,则称此图为连通图。 生成树:一个连通图的最小连通子图称作该图的生成树。有n个顶点的连通图的生成树有n个顶点 和n-1条边。 最小生成树:构成生成树的

    2024年02月05日
    浏览(32)
  • 最小生成树算法之Kruskal算法(c++)

    与Prim算法生成图的最小生成的树算法不同在于: Prim算法是基于图中的顶点的,且不依赖于边,Prim从顶点出发拓展,依次找每个顶点相邻的权值最小的边,直至生成最小生成树。因此,Prim算法的时间复杂度是O(v^2),适合边稠密图。 而Kruskal算法恰恰相反,是基于图中的边的一

    2024年02月12日
    浏览(31)
  • 最小生成树(Prim算法与Kruskal算法)

    一个连通图的生成树是一个极小的连通子图,它含有图中全部的n个顶点,但只有足以构成一棵树的n-1条边。我们把构造连通网的最小代价生成树称为最小生成树。 例如下图中①、②、③都是左侧图的生成树,但③是构造连通网的最小代价,所以③是该图的最小生成树。 P

    2024年02月05日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包