【题解 Kruskal重构树 LCA】 星际导航

星际导航

在这里插入图片描述


分析:

这也是一个比较老的题目了
今天突然想学一下kruskal重构树,就做到了这个题。

首先我们要明白,为什么这道题的路径一定是在最小生成树里?
或许是我们惯有的经验:最小的最大或者最大的最小无非两种套路:
二分答案以及最小生成树。
仔细一想发现二分答案在这道题并不可行。
于是我们将矛头转向了最小生成树。
但是为什么呢?

首先我们明白,两个点之间的路径,其实是一个生成子图,或者说生成子树。
想要最大边最小,其实感性理解一下,就等价于让两个点连通的代价最小。
我们回想最小生成树的思路,这个时候有两个点x和y
如果x和y不连通,说明我们这个时候甚至找不到x和y的一条路径,也就无法求最大边的最小值。
这个时候如果我们在加入一条边v,使得x和y能够连通
那么ok,显然这条边就是我们想找的答案。
也就是x到y路径上的最大边的最小值。
为什么是最大边?
因为这是让x和y连通加入的最后一条边,前面的加边都比他小
为什么是最大的最小?
因为如果我们不要这条边,而选择后面的边,让x和y能够连通,后面的边显然都比他大。
所以又是最小。

这里的最大与最小其实是从两个维度看,理解不同罢了。

那么明白之后其实这道题就变成了Kruskal重构树的模板题。
Kruskal就是将最小生成树的边化为点
边权变成点权
这样子就得到了一颗二叉树
而且原图上的点都是叶子结点
原图上两点的边权就是他们的LCA
因为我们建树加边的时候是按照边权从小到大加边
所以满足越上面的点的边权越大。
于是两个点之间的最大边权就变成了重构树上的LCA的点权。
那么这题就结束了


#include<bits/stdc++.h>
using namespace std;#define int long longconst int N = 3e5+100;
int n,m;
struct E{int x,y,z;
}e[3*N];
int Fa[N][30];
int fa[N];
int cnt;
int v[N*2];
vector < int > a[N];
int d[N]; 
#define pb push_backbool cmp(E x,E y){return x.z < y.z;
}int getfa(int x){return x == fa[x]?x:fa[x] = getfa(fa[x]);
}void Dfs(int x,int faa,int de){d[x] = de;Fa[x][0] = faa;for (int i = 0; i < a[x].size(); i++){int y = a[x][i]; if (y == faa) continue;Dfs(y,x,de+1);}
}void Prefa(){for (int j = 1; j < 30; j++)for (int i = 1; i <= cnt; i++)if (Fa[i][j-1] == -1) Fa[i][j] = -1;else Fa[i][j] = Fa[Fa[i][j-1]][j-1];
}int Lca(int x,int y){if (d[x] < d[y]) swap(x,y);for (int dd = d[x]-d[y],i=0; dd; dd>>=1,i++)if (dd&1) x = Fa[x][i];if (x == y) return x;for (int i = 29; i >= 0; i--)if (Fa[x][i]!=Fa[y][i]) x = Fa[x][i] , y = Fa[y][i];return Fa[x][0];
}signed main(){scanf("%lld %lld",&n,&m);for (int i = 1; i <= n; i++) v[i] = 0;cnt = n;for (int i = 1,x,y,z; i <= m; i++)scanf("%lld %lld %lld",&x,&y,&z),e[i] = {x,y,z};sort(e+1,e+m+1,cmp);for (int i = 1; i < N; i++) fa[i] = i;for (int i = 1; i <= m; i++){int x = e[i].x , y = e[i].y , z = e[i].z;x = getfa(x) , y = getfa(y);if (x == y) continue;++cnt; v[cnt] = z;a[cnt].pb(x); a[cnt].pb(y);a[x].pb(cnt); a[y].pb(cnt);fa[x] = cnt; fa[y] = cnt;}
//	memset(Fa,-1,sizeof Fa);for (int i = cnt; i >= 1; i--)if (!d[i]) Dfs(i,-1,1);Prefa();int q; cin>>q;while (q--){int x,y; cin>>x>>y;int X = getfa(x) , Y = getfa(y);if (X!=Y){cout<<"impossible"<<endl;continue;}int L = Lca(x,y);printf("%lld\n",v[L]);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/48944.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

信号【Linux】

文章目录 信号处理方式&#xff08;信号递达&#xff09;前后台进程 终端按键产生信号kill系统调用接口向进程发信号阻塞信号sigset_tsigprocmasksigpending内核态与用户态&#xff1a;内核空间与用户空间内核如何实现信号的捕捉 1、信号就算没有产生&#xff0c;进程也必须识别…

【C++】C++类和对象详解(上)

目录 思维导图大纲&#xff1a; 思维方面&#xff1a; 1. 类的定义&#xff1a; 2. 类的特点&#xff1a; 3. this指针&#xff1a; 4. 类的默认成员函数 默认构造函数 1.构造函数 2.析构函数 3.拷贝构造函数 4. 赋值运算符重载 1. 运算符重载 5. 日期类实现&#…

【CPP】CPP的内存管理

目录 10 C/C内存管理10.1 内存分布10.2 C的动态内存管理10.3 C的内存管理10.4 new失败的检测10.5 operator new与operator delete函数10.5 new与malloc()的区别,delete与free()的区别10.6 定位new表达式 这里是oldking呐呐,感谢阅读口牙!先赞后看,养成习惯! 个人主页:oldking呐…

编程中的智慧四:设计模式总览

前面三篇我们通过从一些零散的例子&#xff0c;和简单应用来模糊的感受了下设计模式在编程中的智慧&#xff0c;从现在开始正式进入设计模式介绍&#xff0c;本篇将从设计模式的7大原则、设计模式的三大类型、与23种设计模式的进行总结&#xff0c;和描述具体意义。 设计模式体…

使用Diffusion Models进行街景视频生成

Diffusion Models专栏文章汇总&#xff1a;入门与实战 前言&#xff1a;街景图生成相当有挑战性&#xff0c;目前的文本到视频的方法仅限于生成有限范围的场景的短视频&#xff0c;文本到3D的方法可以生成单独的对象但不是整个城市。除此之外街景图对一致性的要求相当高&#x…

数据库基础与安装MYSQL数据库

一、数据库管理系统DBMS 数据库技术是计算机科学的核心技术之一&#xff0c;具有完备的理论基础。使用数据库可以高效且条理分明地存储数据&#xff0c;使人们能够更加迅速、方便地管理数据 1.可以结构化存储大量的数据信息&#xff0c;方便用户进行有效的检索和访问 2.可以…

目前航空航天设备怎么减重设计

目前航空航天设备怎么减重设计 1.使用轻质高强度材料1.1复合材料1.2金属基复合材料1.3陶瓷基复合材料1.4功能梯度材料和蜂窝材料 2.结构优化设计2.1拓扑优化2.2仿生学设计 3.部件和系统轻量化3.1机载娱乐系统3.2航空线缆3.3激光焊接技术 4.发动机和推进系统的优化4.1轻量化发动…

python爬虫Selenium模块及测试案例详解

什么是selenium&#xff1f; &#xff08;1&#xff09;Selenium是一个用于Web应用程序测试的工具。 &#xff08;2&#xff09;Selenium 测试直接运行在浏览器中&#xff0c;就像真正的用户在操作一样。 &#xff08;3&#xff09;支持通过各种driver&#xff08;FirfoxDrive…

python gradio 的输出展示组件

HTML&#xff1a;展示HTML内容&#xff0c;适用于富文本或网页布局。JSON&#xff1a;以JSON格式展示数据&#xff0c;便于查看结构化数据。KeyValues&#xff1a;以键值对形式展示数据。Label&#xff1a;展示文本标签&#xff0c;适用于简单的文本输出。Markdown&#xff1a;…

JavaScript之WebAPIs-BOM

目录 BOM操作浏览器一、Window对象1.1 BOM&#xff08;浏览器对象模型&#xff09;1.2 定时器-延时函数1.3 js执行机制1.4 location对象1.5 navigator对象1.6 history对象 二、本地存储三、补充数组中的map方法数组中的join方法数组中的forEach方法(重点)数组中的filter方法(重…

Linux——Centos系统安装(动图演示)

一、创建虚拟机并做相应配置 打开VMware Workstation&#xff0c;选择创建新的虚拟机&#xff1b; 1、选择自定义选项&#xff1a;点击下一步 2、选择虚拟机硬件兼容性&#xff1a;直接下一步就行了&#xff1b;点击下一步 3、安装客户机操作系统&#xff1a;这里我们选择稍后安…

C++对象模型之绕过private权限修饰符

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、C对象模型二、演示1.类层次2.内存排列 总结 前言 咱们都知道C语言在创建类的时候data member&#xff08;数据成员&#xff09;和fuchtion member&#xf…

Linux操作系统的有关常用的命令

1.linux系统的概述 1.1 什么是Linux系统? Linux&#xff0c;全称GNU/Linux&#xff0c;是一种免费使用和自由传播的类UNIX操作系统&#xff0c;其内核由林纳斯本纳第克特托瓦 兹&#xff08;Linus Benedict Torvalds&#xff09;于1991年10月5日首次发布&#xff0c;它主要受…

LVGL项目实战之UI规划

LVGL项目实战之UI规划 ** 实物购买&#xff1a;TB 南山府嵌入式 ** 我们在在做项目之前&#xff0c;先需要确定项目的需求以及可能实现的功能&#xff0c;我们只有确定这些才能够对整体的框架进行把握。 本小结就说一下我们这个项目的一个整体的框架结构以及功能。 1-硬件构…

C语言实现二叉树以及二叉树的详细介绍

目录 1.树概念及结构 1.1树的概念 1.2树的相关概念 1.3树的表示 2.二叉树概念及结构 2.1二叉树的概念 2.2特殊的二叉树 2.3二叉树的性质 2.4二叉树的存储结构 3.二叉树顺序结构--特殊的二叉树--堆及其实现 3.1堆的概念及结构 3.2堆的实现 3.2.1堆的结构 3.2.2堆…

《JavaSE》---21.<简单认识Java的集合框架包装类泛型>

目录 前言 一、什么是集合框架 1.1类和接口总览 二、集合框架的重要性 2.1 开发中的使用 2.2 笔试及面试题 三、背后所涉及的数据结构 3.1 什么是数据结构 3.2 容器背后对应的数据结构 四、包装类 4.1 基本数据类型和对应的包装类 4.2 装箱和拆箱 1.最初的写法 2.…

org.springframework.context.ApplicationContext发送消息

1、创建消息的实体类 package com.demo;/*** 监听的实体类**/ public class EventMessage {private String name;public EventMessage(String name) {this.name name;}public String getName() {return name;}public void setName(String name) {this.name name;} }2、创建消…

【Linux】如何使用docker快速部署Stirling-PDF并实现远程处理本地文档

文章目录 前言1. 安装Docker2. 本地安装部署StirlingPDF3. Stirling-PDF功能介绍4. 安装cpolar内网穿透5. 固定Stirling-PDF公网地址 前言 本篇文章我们将在Linux上使用Docker在本地部署一个开源的PDF工具——Stirling PDF&#xff0c;并且结合cpolar的内网穿透实现公网随时随…

Java 集合框架:Java 中的双端队列 ArrayDeque 的实现

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 019 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…

共享模型之无锁

一、问题提出 1.1 需求描述 有如下的需求&#xff0c;需要保证 account.withdraw() 取款方法的线程安全&#xff0c;代码如下&#xff1a; interface Account {// 获取余额Integer getBalance();// 取款void withdraw(Integer amount);/*** 方法内会启动 1000 个线程&#xf…