Kruskal 重构树

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

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

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

代码如下:

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

#include <bits/stdc++.h>

using namespace std;
const int MAXN=1e6+50;
int N,M;
struct Edge1
{
int x,y,Len;
}E[MAXN];
struct Edge2
{
int x,y,Next;
}e[MAXN<<1];
int elast[MAXN],tot;
void Add(int x,int y)
{
tot++;
e[tot].x=x;
e[tot].y=y;
e[tot].Next=elast[x];
elast[x]=tot;
}
bool cmp(Edge1 a,Edge1 b)
{
return a.Len<b.Len;
}
int father[MAXN];
int getfather(int x)
{
if(x!=father[x])
father[x]=getfather(father[x]);
return father[x];
}
int f[MAXN][20],depth[MAXN];
int Val[MAXN];
void Kruskal()
{
for(int i=1;i<=2*N-1;i++)
{
father[i]=i;
}
sort(E+1,E+M+1,cmp);
for(int i=1;i<=M;i++)
{
int fx=getfather(E[i].x),fy=getfather(E[i].y);
if(fx!=fy)
{
N++;
father[fx]=N;
father[fy]=N;
Add(N,fx);
Add(N,fy);
Val[N]=E[i].Len;
}
}
}
void dfs(int u,int fa)
{
depth[u]=depth[fa]+1;
f[u][0]=fa;
for(int i=1;f[f[u][i-1]][i-1];i++)
{
f[u][i]=f[f[u][i-1]][i-1];
}
for(int i=elast[u];i;i=e[i].Next)
{
int v=e[i].y;
if(v==fa)
continue;
dfs(v,u);
}
}
int GetLca(int x,int y)
{
if(depth[x]<depth[y])
swap(x,y);
for(int i=19;i>=0;i--)
{
if(depth[f[x][i]]>=depth[y])
{
x=f[x][i];
}
}
if(x==y)
return x;
for(int i=19;i>=0;i--)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
int main()
{
scanf("%d%d",&N,&M);
for(int i=1;i<=M;i++)
{
scanf("%d%d%d",&E[i].x,&E[i].y,&E[i].Len);
E[i].Len=-E[i].Len;
}
Kruskal();
for(int i=N;i>=1;i--)
{
if(depth[i]==0)
dfs(i,0);
} int Q;
scanf("%d",&Q);
while(Q--)
{
int x,y;
scanf("%d%d",&x,&y);
int Lca=GetLca(x,y);
if(Lca==0)
puts("-1");
else
printf("%d\n",-Val[Lca]);
}
}

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

都变成一棵树了,自然想怎么搞事就怎么搞事。既然 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. 设计师必备:免费素材管理工具Billfish v3.0更新了!

    ​​Billfish是专门为设计师打造的图片收藏管理工具,可以轻松管理您的各种素材文件.Billfish是一个免费的软件,支持对大量的图片素材进行管理,提供多种快速的检索筛选功能,如颜色,格式,方向, ...

  2. 使用 ApplicationContextAware 定义 SpringContextHolder 类

    需求:使用 @autowired注入一些对象,但发现不可以直接使用@Autowired,因为方法是static的,要使用该方法当前对象也必须是static,正常情况下@Autowired无法注入静态的 ...

  3. 【事故】记一次意外把企业项目放到GitHub并被fork,如何使用DMCA下架政策保障隐私

    前言 缘由 在一个月黑风高的夜晚,正准备休息的我突然接到之前外包老总的亲切问候.一顿输出才知道三年前为了搭建流程化部署,将甲方的测试代码放到github上后忘记删除.现在被甲方的代码扫描机制扫到,并且 ...

  4. ACM-学习记录-DP-1

    DPL_1_A: Coin Changing Problem 每次均有两种选择,即选择当前的,即为在当前状态+1,否则维持原来的T[j+d[i]] #include<iostream> # ...

  5. NEFUOJ P903字符串去星问题

    Description 有一个字符串(长度小于100),要统计其中有多少个,并输出该字符串去掉后的新字符串. Input 输入数据有多组,每组1个连续的字符串; Output 在1行内输出该串内有多少 ...

  6. WPF 界面布局、常用控件入门教程实例 WPF入门学习控件快速教程例子 WPF上位机、工控串口通信经典入门

    WPF(Windows Presentation Foundation)是一种用于创建 Windows 桌面应用程序的框架,它提供了丰富的控件库和灵活的界面布局,可以创建现代化的用户界面.下面是 WP ...

  7. C++ 测试框架 GoogleTest 初学者入门篇 乙

    *以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/aFeiOGO-N9O7Ab_8KJ2wxw 开发者虽然主要负责工程 ...

  8. 管理WEB服务器文件的WebDAV协议&HTTP大跃进--QUIC与HTTP30&WEB安全攻击概述

    管理WEB服务器文件的WebDAV协议 WebADV协议 WEBDAV追加方法 WeDAV请求示例 HTTP大跃进--QUIC与HTTP30 QUIC&HTTP3.0 HTTP2.0的问题 队 ...

  9. Redis读书笔记(一)

    Redis数据结构 1 简单动态字符串 Simple dynamic string 的实现 // sds.h/sdshdr struct sdshdr { int len; //记录buf数组中已使用 ...

  10. spring-boot-starter-parent not found

    项目开始的springboot版本为2.6.6 <parent> <groupId>org.springframework.boot</groupId> <a ...