【并查集、树的直径】P2195 HXY造公园 题解

题意

P2195 codeforces 455c,两道一样的题

给出一个由 n n n 个点, m m m 条边组成的森林,有 q q q 组询问,每次询问有以下两种情况

输入 o p = 1 op = 1 op=1 时:给出点 x x x,输出点 x x x 所在的树的直径。
输入 o p = 2 op = 2 op=2 时:给出点 x , y x,y x,y,(如果 x , y x,y x,y 在同一棵树中则忽略此操作)选择任意两点 u , v u,v u,v,使得 $u 跟 x x x 在同一棵树中且 v v v y y y 在同一棵树中。将 u , v u,v u,v 之间连一条边,使得连边后的到的新树的直径最小。

思路

首先毫无疑问找到每一棵树的“核”,即直径的终点。在此基础上我们保存 d e e p e s t i deepest_i deepesti d e e p e s t 2 i deepest2_i deepest2i,表示以这个核为根节点的树前两个最长的链(互不重合),则 d e e p e s t i + d e e p e s t 2 i deepest_i + deepest2_i deepesti+deepest2i 则表示当前直径。

考虑操作 1 1 1,我们输出 d e e p e s t i + d e e p e s t 2 i deepest_i + deepest2_i deepesti+deepest2i 即可。

考虑操作 2 2 2。因为合并两棵树(如果已经是一棵树则不用合并,合并和找根节点用并查集可以实现,可前往并查集入门学习)后树的直径长度不会改变,因此令 x ← f i n d ( x ) , y ← f i n d ( y ) x \gets find(x),y \gets find(y) xfind(x),yfind(y) f i n d find find 操作表示并查集中找到根节点。合并时显而易见只要合并两个根节点即可

  • 考虑 d e e p e s t x = d e e p e s t y deepest_x = deepest_y deepestx=deepesty 情况,如图所示,原来 4 , 5 , 6 4,5,6 4,5,6 1 , 2 , 3 1,2,3 1,2,3 分别为 2 2 2 棵树,加根后因为 1 1 1 加到 4 4 4 地下, d e e p e s t x ← d e e p e s t x + 1 deepest_x \gets deepest_x + 1 deepestxdeepestx+1

在这里插入图片描述

  • 考虑 两个最深的链不等的情况,不妨令 d e e p e s t x > d e e p e s t y deepest_x > deepest_y deepestx>deepesty,则考虑对第二深的链的影响。如果 d e e p e s t y + 1 > d e e p e s t 2 x deepest_y + 1 > deepest2_x deepesty+1>deepest2x,则更新 d e e p e s t 2 x = d e e p e s t y + 1 deepest2_x = deepest_y + 1 deepest2x=deepesty+1

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int fat[600005];
int find(int x) {return fat[x] == x?x:fat[x] = find(fat[x]);
}
int head[600005],nex[1200005],to[1200005],cnt;
int add(int x,int y) {nex[++cnt] = head[x];head[x] = cnt;to[cnt] = y;
}
int n,m,q; 
bool v[600005];
int maxx,ed1,ed2,root;
int deepest[600005],deepest2[600005];
void find_edge1(int now,int fa,int deep) {for(int i = head[now];i;i = nex[i]) {if(to[i] != fa) find_edge1(to[i],now,deep + 1);}if(deep >= maxx) {maxx = deep;ed1 = now;}return;
}
void find_edge2(int now,int fa,int deep) {for(int i = head[now];i;i = nex[i]) {if(to[i] != fa) find_edge2(to[i],now,deep + 1);}if(deep >= maxx) {maxx = deep;ed2 = now;}return;
}
void find_root(int now,int fa,int deep) {if(now == ed2) {v[now] = 1;}for(int i = head[now];i;i = nex[i]) {if(to[i] != fa) {find_root(to[i],now,deep + 1);if(v[to[i]]) v[now] = 1;}}if(v[now] and deep == maxx / 2) {root = now;deepest[root] = maxx - deep;deepest2[root] = maxx / 2;}
}
void biaoji(int now,int fa) {for(int i = head[now];i;i = nex[i]) {if(to[i] != fa) biaoji(to[i],now);}v[now] = 1;fat[now] = root;
}
signed main() {scanf("%lld %lld %lld",&n,&m,&q);for(int i = 1;i <= n;i++) fat[i] = i;while(m--) {int x,y;scanf("%lld %lld",&x,&y);add(x,y),add(y,x);}for(int i = 1;i <= n;i++) {if(!v[i]) {maxx = 0;find_edge1(i,i,0);maxx = 0;find_edge2(ed1,ed1,0);find_root(ed1,ed1,0);biaoji(ed1,ed1);//	printf("%lld %lld %lld\n",ed1,ed2,root);}}for(int i = 1;i <= q;i++) {int op,x,y;scanf("%lld",&op);if(op == 1) {scanf("%lld",&x);printf("%lld\n",deepest[find(x)] + deepest2[find(x)]);}if(op == 2) {scanf("%lld %lld",&x,&y);x = find(x),y = find(y);if(x == y) continue;//printf("%lld %lld\n",deepest[x],deepest[y]);if(deepest[x] == deepest[y]) {fat[y] = x;deepest[x]++;deepest2[x] = deepest[y];}else if(deepest[x] > deepest[y]) {fat[y] = x;if(deepest2[x] < deepest[y] + 1) deepest2[x] = deepest[y] + 1;}else {fat[x] = y;if(deepest2[y] < deepest[x] + 1) deepest2[y] = deepest[x] + 1;}}}return 0;
}

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

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

相关文章

Linux--C语言之分支结构

文章目录 一、分支结构&#xff08;一&#xff09;概念&#xff08;二&#xff09;条件构建1.关系表达式&#xff1a;2.逻辑表达式&#xff1a;3.常量/变量&#xff1a;值是否非0&#xff0c;取值&#xff08;0|1&#xff09; &#xff08;三&#xff09;选择结构的形式1.单分支…

idea项目注册在nacos错误:Cannot determine local hostname

一开始想把项目注册在nacos上&#xff0c;启动报错是这样的&#xff0c;而且yml文件也不生效&#xff0c;因为默认端口是8080&#xff0c;我在yml文件中写了8081没用&#xff0c;正好nacos的配置也在yml文件中。各种百度&#xff0c;各种依赖添加删除&#xff0c;反复启动没用 …

振德医疗选择泛微千里聆RPA,助力电商、人事业务流程自动化

振德医疗用品股份有限公司成立于1994年&#xff0c;中国A股上市公司&#xff0c;是医用敷料和感控防护产品主要的供应商之一。 &#xff08;图片素材来自振德医疗官网&#xff09; 振德医疗的业务在线上线下齐发力。目前拥有5个国内生产基地&#xff0c;3个海外工厂&#xff0…

SQL Server 2022的游标

《SQL Server 2022从入门到精通&#xff08;视频教学超值版&#xff09;》图书介绍-CSDN博客 《SQL Server 2022从入门到精通&#xff08;视频教学超值版&#xff09;&#xff08;数据库技术丛书&#xff09;》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) 游标是SQL Serv…

分布式知识总结(一致性Hash算法)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 一致性Hash算法 假如有三台服务器编号node0、node1、node2&…

【系统维护】Dll文件修复工具使用教程,Windows系统必备!

一、dll文件是什么 dll文件是是一种Windows操作系统下的可执行文件格式&#xff0c;包含可由多个程序同时使用的代码和数据的文件&#xff0c;它的主要作用是实现代码和数据的共享&#xff0c;从而节省内存和硬盘空间&#xff0c;并提高程序的性能和可维护性 二、如何解决dll文…

云计算实训26——部署LVS负载均衡项目

LVS LVS是linux virtural server的简称——免费、开源、四层负载均衡 工作原理&#xff1a; 通过linux达到负载均衡好和linux操作系统实现高性能高可用的linux服务集群&#xff0c;具有良好的可靠性、可扩展性、可操作性、可扩展性、从而实现以低廉的成本实现最优的性能。LV…

PTA 7-21 求特殊方程的正整数解

7-21 求特殊方程的正整数解&#xff08;15分&#xff09; 本题要求对任意给定的正整数N&#xff0c;求方程的全部正整数解。 输入格式&#xff1a; 输入在一行中给出正整数N&#xff08;≤10000&#xff09;。 输出格式&#xff1a; 输出方程的全部正整数解&#xff0c;其…

Wise Registry Cleaner:程序员必备的电脑加速工具!

前言 但你知道吗&#xff1f;随着时间的推移&#xff0c;Windows注册表就像是一个不断膨胀的宇宙&#xff0c;里面充满了无效、过时或残留的“星际垃圾”&#xff1b;这些看似不起眼的碎片&#xff0c;却在悄然间拖慢了你的电脑速度&#xff0c;让系统变得不那么“听话”&#…

CSS3下拉菜单实现

导航菜单&#xff1a; <nav class"multi_drop_menu"><!-- 一级开始 --><ul><li><a href"#">Power</a></li><li><a href"#">Money</a></li><li><a href"#"…

React + React-tsparticles + Tsparticles完成炫酷的登录特效

效果(动态) npm i react-tsparticles2.12.2 npm i tsparticles2.12.0 注意:最好和上面的版本一样,不然会出现一个报错,具体如何解决的话去官网吧,上面的版本是没有问题的 代码块 总计6个代码块, options里面是相关粒子的配置 完整代码 import ./index.sass import { Form, Inp…

【简历】宜宾某学院简历:通过率低,JVM是必考点,不能写了解

注&#xff1a;为保证用户信息安全&#xff0c;姓名和学校等信息已经进行同层次变更&#xff0c;内容部分细节也进行了部分隐藏 简历说明 这是一份25届的宜宾某二本学院的Java简历&#xff0c;那么这个简历&#xff0c;因为说二本的校招&#xff0c;主体在小公司&#xff0c;…

Redis的过期策略与内存淘汰机制详解

文章目录 Redis的过期策略1. 定时删除2. 惰性删除3. 定期删除 Redis的内存淘汰机制1. noeviction2. volatile-random3. volatile-ttl4. volatile-lru5. volatile-lfu6. allkeys-random7. allkeys-lru8. allkeys-lfu LRU与LFU算法总结 Redis作为一种高性能的键值对存储系统&…

OJ-0813

题目 示例&#xff1a; 输入&#xff1a; 1-2abcd 输出&#xff1a; -1参考 import java.util.Arrays; import java.util.HashSet; import java.util.Scanner; import java.util.Set; import java.util.Stack;public class Main {// 保存数字的栈static Stack<Long> nu…

Qt使用lupdate工具生成.ts文件

Qt提供了lupdate工具&#xff0c;用于从源代码中提取需要翻译的字符串【1】&#xff0c;并生成或更新.ts文件 注解【1】&#xff1a;使用tr()函数&#xff08;或者QCoreApplication::translate()等其他相关的翻译函数&#xff09;来标记所有需要翻译的文本。例如&#xff1a; …

WEB应用(十五)---文件包含

文件包含的概念 在各种开发语言中都提供了内置的文件包含函数&#xff0c;可以使得开发人员在一个代码文件中直接包含&#xff08;引入&#xff09;另外一个代码文件。 由于文件包含可以达到复用和方便修改的目的&#xff0c;在代码设计中常常使用。 大多数情况下&#xff0…

Ethercat学习-SOEM主站源码解析(DC部分)

文章目录 SOEM DC模式源码简介示例用图ecx_porttimeecx_parentportecx_configdc如果从站不支持DC如果从站支持DC SOEM DC模式源码简介 示例用图 本文中都会围绕着这个图来讲&#xff0c;从站的port编号依次为0&#xff0c;3&#xff0c;1&#xff0c;2 在SOEM中&#xff0c;与…

【vulnhub】Broken: Gallery靶机

靶机安装 下载地址&#xff1a;Broken: Gallery ~ VulnHub 信息收集 靶机IP发现 nmap 192.168.93.0/24 端口扫描 nmap -A 192.168.93.167 -p- 目录扫描 dirsearch -u http://192.168.93.167 页面访问&#xff0c; 没有可用的信息 尝试22端口的ssh进行爆破 hydra -L roc…

算法的学习笔记——二进制中 1 的个数(牛客JZ15)

&#x1f600;前言 在计算机科学中&#xff0c;二进制是计算和存储数据的基础。理解二进制中的基本运算有助于我们解决各种编程问题。一个经典的问题是&#xff1a;给定一个整数&#xff0c;如何快速计算该整数的二进制表示中1的个数。 &#x1f3e0;个人主页&#xff1a;尘觉主…

【计算机毕设】基于SpringBoot的教育局综合信息管理平台-学生端

&#x1f497;博主介绍&#xff1a;✌全平台粉丝5W,高级大厂开发程序员&#x1f603;&#xff0c;博客之星、掘金/知乎/华为云/阿里云等平台优质作者。 【源码获取】关注并且私信我 【联系方式】&#x1f447;&#x1f447;&#x1f447;最下边&#x1f447;&#x1f447;&…