Kruskal 重构树

是一棵二叉树,一张 \(N\) 个点的无向连通图的 Kruskal 重构树有 \(2N-1\) 个节点。

叶子节点为原图中节点,非叶子节点有点权,表示想在原图上从一边的子树内的叶子节点所对应的原图上节点走到另一边的子树内的叶子节点所对应的原图上节点所需经过的最长边的最小可能值。

建树方式:Kruskal 每次合并 \(2\) 个节点时,新开一个点,记作这 \(2\) 个节点的重构树父亲(及并查集父亲),权值为当前这条边的权值。

代码如下:

(花15分钟敲完的模板题 [NOIP2013 提高组] 货车运输

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int MAXN=1e6+50;
  4. int N,M;
  5. struct Edge1
  6. {
  7. int x,y,Len;
  8. }E[MAXN];
  9. struct Edge2
  10. {
  11. int x,y,Next;
  12. }e[MAXN<<1];
  13. int elast[MAXN],tot;
  14. void Add(int x,int y)
  15. {
  16. tot++;
  17. e[tot].x=x;
  18. e[tot].y=y;
  19. e[tot].Next=elast[x];
  20. elast[x]=tot;
  21. }
  22. bool cmp(Edge1 a,Edge1 b)
  23. {
  24. return a.Len<b.Len;
  25. }
  26. int father[MAXN];
  27. int getfather(int x)
  28. {
  29. if(x!=father[x])
  30. father[x]=getfather(father[x]);
  31. return father[x];
  32. }
  33. int f[MAXN][20],depth[MAXN];
  34. int Val[MAXN];
  35. void Kruskal()
  36. {
  37. for(int i=1;i<=2*N-1;i++)
  38. {
  39. father[i]=i;
  40. }
  41. sort(E+1,E+M+1,cmp);
  42. for(int i=1;i<=M;i++)
  43. {
  44. int fx=getfather(E[i].x),fy=getfather(E[i].y);
  45. if(fx!=fy)
  46. {
  47. N++;
  48. father[fx]=N;
  49. father[fy]=N;
  50. Add(N,fx);
  51. Add(N,fy);
  52. Val[N]=E[i].Len;
  53. }
  54. }
  55. }
  56. void dfs(int u,int fa)
  57. {
  58. depth[u]=depth[fa]+1;
  59. f[u][0]=fa;
  60. for(int i=1;f[f[u][i-1]][i-1];i++)
  61. {
  62. f[u][i]=f[f[u][i-1]][i-1];
  63. }
  64. for(int i=elast[u];i;i=e[i].Next)
  65. {
  66. int v=e[i].y;
  67. if(v==fa)
  68. continue;
  69. dfs(v,u);
  70. }
  71. }
  72. int GetLca(int x,int y)
  73. {
  74. if(depth[x]<depth[y])
  75. swap(x,y);
  76. for(int i=19;i>=0;i--)
  77. {
  78. if(depth[f[x][i]]>=depth[y])
  79. {
  80. x=f[x][i];
  81. }
  82. }
  83. if(x==y)
  84. return x;
  85. for(int i=19;i>=0;i--)
  86. {
  87. if(f[x][i]!=f[y][i])
  88. {
  89. x=f[x][i];
  90. y=f[y][i];
  91. }
  92. }
  93. return f[x][0];
  94. }
  95. int main()
  96. {
  97. scanf("%d%d",&N,&M);
  98. for(int i=1;i<=M;i++)
  99. {
  100. scanf("%d%d%d",&E[i].x,&E[i].y,&E[i].Len);
  101. E[i].Len=-E[i].Len;
  102. }
  103. Kruskal();
  104. for(int i=N;i>=1;i--)
  105. {
  106. if(depth[i]==0)
  107. dfs(i,0);
  108. }
  109. int Q;
  110. scanf("%d",&Q);
  111. while(Q--)
  112. {
  113. int x,y;
  114. scanf("%d%d",&x,&y);
  115. int Lca=GetLca(x,y);
  116. if(Lca==0)
  117. puts("-1");
  118. else
  119. printf("%d\n",-Val[Lca]);
  120. }
  121. }

注意到由于此题是求最大生成树,所以在输入时将边权取反,就变成了最小生成树。

都变成一棵树了,自然想怎么搞事就怎么搞事。既然 LCT 可以维护最小生成树,所以 LCT 维护 Kruksal 重构树应该也是可以的罢?

Kruskal 重构树满足父亲节点的权值不小于其子节点,所以在树上倍增这样的操作也是很常见的。

Kruskal 重构树的更多相关文章

  1. [bzoj 3732] Network (Kruskal重构树)

    kruskal重构树 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1-N. 图中有M条边 (1 <= M <= 30,000) ,第 ...

  2. 【BZOJ 3732】 Network Kruskal重构树+倍增LCA

    Kruskal重构树裸题, Sunshine互测的A题就是Kruskal重构树,我通过互测了解到了这个神奇的东西... 理解起来应该没什么难度吧,但是我的Peaks连WA,,, 省选估计要滚粗了TwT ...

  3. 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 321[Submit][Sta ...

  4. BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]

    3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...

  5. bzoj 3551 kruskal重构树dfs序上的主席树

    强制在线 kruskal重构树,每两点间的最大边权即为其lca的点权. 倍增找,dfs序对应区间搞主席树 #include<cstdio> #include<cstring> ...

  6. kruskal重构树学习笔记

    \(kruskal\) 重构树学习笔记 前言 \(8102IONCC\) 中考到了,本蒟蒻不会,所以学一下. 前置知识 \(kruskal​\) 求最小(大)生成树,树上求 \(lca​\). 算法详 ...

  7. Kruskal重构树入门

    这个知识点好像咕咕咕了好长了..趁还没退役赶紧补一下吧.. 讲的非常简略,十分抱歉.. 前置知识 Kruskal算法 一定的数据结构基础(如主席树) Kruskal重构树 直接bb好像不是很好讲,那就 ...

  8. UOJ#407. 【IOI2018】狼人 Kruskal,kruskal重构树,主席树

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ407.html 题解 套路啊. 先按照两个节点顺序各搞一个kruskal重构树,然后问题转化成两棵krus ...

  9. LOJ.2865.[IOI2018]狼人(Kruskal重构树 主席树)

    LOJ 洛谷 这题不就是Peaks(加强版)或者归程么..这算是\(IOI2018\)撞上\(NOI2018\)的题了? \(Kruskal\)重构树(具体是所有点按从小到大/从大到小的顺序,依次加入 ...

  10. 洛谷P4768 [NOI2018]归程(Kruskal重构树)

    题意 直接看题目吧,不好描述 Sol 考虑暴力做法 首先预处理出从$1$到每个节点的最短路, 对于每次询问,暴力的从这个点BFS,从能走到的点里面取$min$ 考虑如何优化,这里要用到Kruskal重 ...

随机推荐

  1. 关于VScode vue3卡顿

    在使用vscode+volar开发vue3项目时,出现代码提示缓慢的问题.通过开启Volar Takeover *模式解决. 以下摘自Vue3官网 https://cn.vuejs.org/guide ...

  2. 可靠消息最终一致性【本地消息表、RocketMQ 事务消息方案】

    更多内容,前往IT-BLOG 一.可靠消息最终一致性事务概述 可靠消息最终一致性方案是指当事务发起方执行完成本地事务后并发出一条消息,事务参与方(消息消费者)一定能够接收消息并处理事务成功,此方案强调 ...

  3. [Python]【Form Data vs Request Payload】之 python 爬虫如何实现 POST request payload 形式的请求

    1 问题描述 欲使用Python的requests库(requests.session().request(...))实现对此Ajax的POST请求进行模拟实现. 但在chrome发现其请求的形式不一 ...

  4. Django笔记十七之group by 分组用法总结

    本文首发于微信公众号:Hunter后端 原文链接:Django笔记十七之group by 分组用法总结 这篇笔记介绍 Django 里面 model 的 group by 对应的一些操作. 用到的 M ...

  5. 【Diary】CSP-S2 2021 游记 & NOIP 备赛发疯日记

    Day 0 两个极端的回跳. .....不行啊. 我快输不起了........... ------------------------------- 早上被生物钟强行唤醒,逼自己懒床到6:40. 弹琴 ...

  6. Redis缓冲区溢出及解决方案

    缓冲区(buffer),是内存空间的一部分.也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区. 一.Redis缓冲区溢出影响 在Redis ...

  7. Solon2 常用注解之 @ProxyComponent 用法说明

    在 Solon 提倡"克制"的原则下,托管组件分为: 普通组件 代理组件(即 @ProxyComponent 注解的类).代理的细节可以看下<动态代理的本质> . 之所 ...

  8. 微服务为什么要用到 API 网关?

    本文介绍了 API 网关日志的价值,并以知名网关 Apache APISIX 为例,展示如何集成 API 网关日志. 作者程小兰,API7.ai 技术工程师,Apache APISIX Contrib ...

  9. Mapstruct使用报java: Couldn't retrieve @Mapper annotation

    检查代码报错 java: Couldn't retrieve @Mapper annotation jar包冲突,去掉一个Mapstructjar包.

  10. js计算当前时间差

    1 function timesFun(timesData) { 2 //如果时间格式是正确的,那下面这一步转化时间格式就可以不用了 3 var dateBegin = new Date(timesD ...