【学习笔记】kruskal重构树

news2024/12/28 22:22:49

前言

最近一场div2没开出C2,猛掉104分。
赛后补E,发现自己连E1都没思路,一问才知道是kruskal重构树。
好吧,OI时期欠下的债该还了。

kruskal重构树是什么

  1. 它是一棵 2 n − 1 2n-1 2n1 个点的二叉树。点有点权,下面记作 v a l x val_x valx
  2. 它是一个 大/小根堆,如果是最小生成树构建的就是大根堆,反之,如果是最大生成树构建的就是小根堆。
  3. 对于原图上的每一对点 ( x , y ) (x,y) (x,y),他们之间的最小/大边权 v a l x , y val_{x,y} valx,y,如果是最小生成树那就是最小边权,反之亦然。
  4. 重构树所有叶子都是原图上的点,其他的点都不是原图上的点。
  5. 如果原图不连通,你会得到一个重构树森林。

算法流程

  1. 把边按照边权排序。
  2. 初始化并查集。注意重构树有 2 n − 1 2n-1 2n1 个点,所以要开一个大小为 2 n − 1 2n-1 2n1 的并查集。
  3. r t rt rt 为当前最大的点的编号,初始化 r t = n rt=n rt=n
  4. 和 kruskal 一样,按顺序枚举边,如果两个点属于同一个集合就 continue,令 u = g e t f a t h e r ( x ) ,   v = g e t f a t h e r ( y ) u=getfather(x),\ v=getfather(y) u=getfather(x), v=getfather(y)
  5. r t + + rt++ rt++ f a u = f a v = r t fa_u=fa_v=rt fau=fav=rt v a l r t = w x , y val_{rt}=w_{x,y} valrt=wx,y。也就是新建一个点作为 u 和 v 的父亲,并令它的点权等于边权。

例题

[NOI2018] 归程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路

毫无疑问,我们肯定要预处理所有点到 1 号点的最短路。
如果是在最大生成树上跑的话,你会发现根本没法做。
考虑根据海拔建 kruskal 重构树。对于一个点 u,如果 v a l u > p val_u>p valu>p v a l f a u ≤ p val_{fa_u}\leq p valfaup,那么 u u u 子树内的所有点都是可以不花任何代价互相到达的。于是我们需要预处理子树内的点到达 1 号点的最短距离,dfs即可。
对于一个出发点 v v v,我们需要找到最后一个没有被淹没的祖先,用倍增即可。

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+7,inf=1e18,mod=998244353,S=21;
vector<vector<int>> e,f;
vector<vector<array<int,2>>> E;
vector<int> val,dis,fa;
int n,m;
int gf(int x)
{
	return x==fa[x]?x:fa[x]=gf(fa[x]);
}
void dij()
{
	priority_queue<array<int,2>,vector<array<int,2>>,greater<array<int,2>>> q;
	q.push({0,1});
	dis.assign(2*n,inf);
	dis[1]=0;
	vector<int> vis(n+1);
	while(!q.empty())
	{
		int u=q.top()[1]; q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(auto [v,w]:E[u])
		{
			if(vis[v]||dis[u]+w>=dis[v])
				continue;
			dis[v]=dis[u]+w;
			q.push({dis[v],v});
		}
	}
}
void dfs(int u,int fa)
{
	f[u][0]=fa;
	for(int j=1; j<S; j++)
	{
		f[u][j]=f[f[u][j-1]][j-1];
	}
	for(auto v:e[u])
	{
		dfs(v,u);
		dis[u]=min(dis[u],dis[v]);
	}
}
int query(int u,int p)
{
	for(int i=S-1; i>=0; i--)
	{
		if(val[f[u][i]]>p)
			u=f[u][i];
	}
	return dis[u];
}
void O_o()
{
	cin>>n>>m;
	e.assign(n*2,vector<int>());
	val.assign(n*2,0);
	vector<array<int,4>> edge;//a,l,u,v
	E.assign(n+1,vector<array<int,2>>());
	for(int i=1; i<=m; i++)
	{
		int u,v,l,a;
		cin>>u>>v>>l>>a;
		E[u].push_back({v,l});
		E[v].push_back({u,l});
		edge.push_back({a,l,u,v});
	}
	dij();
	sort(edge.begin(),edge.end(),greater<>());
	fa.assign(2*n,0);
	for(int i=1; i<=n*2-1; i++) fa[i]=i;
	int rt=n;
	for(auto [a,l,x,y]:edge)
	{
		int u=gf(x),v=gf(y);
		if(u==v) continue;
		rt++;
		fa[u]=rt;
		fa[v]=rt;
		e[rt].push_back(u);
		e[rt].push_back(v);
		val[rt]=a;
	}
	f.assign(2*n,vector<int>(21,0));
	dfs(rt,0);
	int Q,K,S;
	cin>>Q>>K>>S;
	int ans=0;
	while(Q--)
	{
		int v,p;
		cin>>v>>p;
		v=(v+K*ans-1)%n+1;
		p=(p+K*ans)%(S+1);
		ans=query(v,p);
		cout<<ans<<"\n";
	}
}
signed main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cout<<fixed<<setprecision(12);
	int T=1;
	cin>>T;
	while(T--)
	{
		O_o();
	}
}

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

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

相关文章

深入挖掘C++中的特性之一 — 多态

目录 1.多态的概念 2.多态的定义及其实现 1.虚函数 2.虚函数的重写/覆盖 3.实现多态的必要条件 4.多态的代码呈现 5.来一道小题&#xff0c;深入理解一下多态 3.虚函数重写的一些其他问题 1.协变 2.析构函数的重写 4.override和final关键字 5.重载/重写/隐藏的对比&…

动态规划算法专题(四):子串、子数组系列

目录 1、最大子数组和 1.1 算法原理 1.2 算法代码 2、环形子数组的最大和 2.1 算法原理 2.2 算法代码 3、乘积最大子数组 3.1 算法原理 3.2 算法代码 4、乘积为正数的最长子数组长度 4.1 算法原理 4.2 算法代码 5、等差数列划分 5.1 算法原理 5.2 算法代码 6、…

C++读取大文件三种方法速度比较

目录 测试说明第一种方法&#xff1a;按块读&#xff0c;一次读8kb第二种方法&#xff1a;按行读&#xff0c;一次读一行第三种方法&#xff1a;多线程并行读取完整示例 测试说明 测试文件&#xff1a;100万行&#xff0c;每一行是两个小数&#xff0c;中间用逗号隔开&#xf…

python脚本实现Redis未授权访问漏洞利用

之前介绍过Redis未授权访问漏洞&#xff0c;本文使用python实现Redis未授权访问检测以及对应三种getshell。 1 测试环境准备 CentOS 7&#xff08;192.168.198.66/24&#xff09;&#xff1a;安装 Redis 服务器并用 root 权限开启服务&#xff0c;关闭保护模式&#xff1b;安…

4-coumarate--CoA ligase4-香豆酸:辅酶A连接酶4CL-文献精读63

Characterization and Functional Analysis of 4-Coumarate:CoA Ligase Genes in Mulberry 桑树中4-香豆酸&#xff1a;辅酶A连接酶基因的表征与功能分析 桑树T2T基因组-文献精读16 摘要 4-香豆酸&#xff1a;辅酶A连接酶&#xff08;4CL&#xff09;由一个小型的多基因家族…

pytest(六)——allure-pytest的基础使用

前言 一、allure-pytest的基础使用 二、需要掌握的allure特性 2.1 Allure报告结构 2.2 Environment 2.3 Categories 2.4 Flaky test 三、allure的特性&#xff0c;allure.step()、allure.attach的详细使用 3.1 allure.step 3.2 allure.attach&#xff08;挺有用的&a…

软件测试比赛-学习

一、环境配置 二、浏览器适配 //1.设置浏览器的位置,google浏览器位置是默认且固定在电脑里的//2.设置浏览器驱动的位置,C:\Users\27743\AppData\Local\Google\Chrome\ApplicationSystem.setProperty("webdriver.chrome.driver", "C:\\Users\\27743\\AppData\\…

【python实操】python小程序之对象的属性操作

引言 python小程序之对象的属性操作 文章目录 引言一、对象的属性操作1.1 题目1.2 代码1.3 代码解释 二、思考2.1 添加属性2.2 获取属性 一、对象的属性操作 1.1 题目 给对象添加属性 1.2 代码 class Cat:# 在缩进中书写⽅法def eat(self):# self 会⾃动出现,暂不管print(f…

弹性分布式数据集RDD详细说明

文章目录 整体介绍一、定义与特性二、操作与转换三、存储级别与持久化四、依赖关系与容错机制五、优化与性能调优 常见操作支持的数据格式1.文本文件 (Text Files)2. CSV 文件3. JSON 文件4. Parquet 文件5. Sequence Files6.Hadoop文件读取A. 读取HDFS上的文本文件B. 使用Hado…

(Linux驱动学习 - 8).信号异步通知

一.异步通知简介 1.信号简介 信号类似于我们硬件上使用的“中断”&#xff0c;只不过信号是软件层次上的。算是在软件层次上对中断的一种模拟&#xff0c;驱动可以通过主动向应用程序发送信号的方式来报告自己可以访问了&#xff0c;应用程序获取到信号以后就可以从驱动设备中…

论文阅读——联邦忘却学习研究综述

文章基本信息 作者&#xff1a; 王鹏飞魏宗正周东生宋威肖蕴明孙庚于硕张强 机构&#xff1a; 大连理工大学计算机科学与技术学院大连理工大学社会计算与认知智能教育部重点实验室大连大学先进设计与智能计算教育部重点实验室美国西北大学计算机科学系吉林大学计算机科学与…

QT调用libusb库stm32407上下位机

安富莱USB上位机教程 参考安富莱的视频&#xff0c;不过这里 调用是libusb最新的库 可以参考上一个文章&#xff1a; QT调用最新的libusb库 https://editor.csdn.net/md/?articleId142733711 调试结果&#xff1a; 资源地址&#xff1a; 上位机&#xff1a;https://downl…

基于pytorch的手写数字识别-训练+使用

import pandas as pd import numpy as np import torch import matplotlib import matplotlib.pyplot as plt from torch.utils.data import TensorDataset, DataLoadermatplotlib.use(tkAgg)# 设置图形配置 config {"font.family": serif,"mathtext.fontset&q…

Maven 高级之分模块设计与继承、聚合

在软件开发中&#xff0c;随着项目规模的扩大&#xff0c;代码量和复杂度不断增加&#xff0c;传统的一体化开发模式逐渐暴露出诸多问题。为了解决这些问题&#xff0c;模块化开发应运而生&#xff0c;而 Maven 正是模块化开发的利器&#xff0c;它提供的继承和聚合机制为构建和…

fiddler抓包20_弱网模拟

课程大纲 ① 打开CustomRules.js文件&#xff1a;Fiddler快捷键“CtrlR”(或鼠标点击&#xff0c;菜单栏 - Rules - Customize Rules)。 ② 设置速率&#xff1a;“CtrlF”&#xff0c;搜索 “m_SimulateModem”&#xff0c;定位至函数。在函数里设置上传、下载速率&#xff0c…

ESP8266模块(WIFI STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.ESP8266基础AT指令介绍 4.ESP8266基础工作模式 三、程序设计 main.c文件 esp8266.h文件 esp8266.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 ESP8266是一款嵌入式系统级芯片&#xff0c;它集成了Wi…

将自己写好的项目部署在自己的云服务器上

准备工作 这里呢我要下载的终端软件是Xshell 如图&#xff1a; 自己准备好服务器&#xff0c;我这里的是阿里云的服务器&#xff0c; 如图&#xff1a; 这两个准备好之后呢&#xff0c;然后对我们的项目进行打包。 如图&#xff1a; 这里双击打包就行了。 找到自己打成jar包…

零基础多图详解图神经网络(GNN/GCN)【李沐论文精读】

A Gentle Introduction to Graph Neural Networks 在上图中&#xff0c;每一层都是一层网络&#xff0c;每一层的节点都受到下一层中自身节点和邻居节点的影响。如果网络比较深&#xff0c;是可以处理到一幅图中较大范围的节点。 前言 图神经网络在应用上还只是起步阶段&…

基于SpringBoot健身房管理系统【附源码】

效果如下&#xff1a; 系统首页界面 系统注册详细页面 健身课程详细页面 后台登录界面 管理员主页面 员工界面 健身教练界面 员工主页面 健身教练主页面 研究背景 随着生活水平的提高和健康意识的增强&#xff0c;现代人越来越注重健身。健身房作为一种专业的健身场所&#x…

日期类的实现(C++)

个人主页&#xff1a;Jason_from_China-CSDN博客 所属栏目&#xff1a;C系统性学习_Jason_from_China的博客-CSDN博客 所属栏目&#xff1a;C知识点的补充_Jason_from_China的博客-CSDN博客 前言 日期类是六个成员函数学习的总结和拓展&#xff0c;是实践的体现 创建文件 构造函…