首页 > 其他分享 >[题解]P9433 [NAPC-#1] Stage5 - Conveyors

[题解]P9433 [NAPC-#1] Stage5 - Conveyors

时间:2024-06-10 19:10:35浏览次数:24  
标签:dist -# 19 int 题解 P9433 fa ans dis

P9433 [NAPC-#1] Stage5 - Conveyors

题意简述

给定一个\(N\)个节点的树形结构,每条边有边权,树上有\(k\)个关键点。

接下来有\(q\)次询问,每次询问给定\(x,y\)两点,请计算从\(x\)开始经过这\(k\)个关键点(可以重复经过)再到\(y\)的最短路程。

解题思路

我们可以发现,如果\(x\)与\(y\)都在\(k\)个关键点所形成的最小子图中,那么答案就是这个子图中所有边长度之和\(w\)的两倍,再减去\(x\)到\(y\)的距离,即\(2w-dist(x,y)\)。

为什么呢?因为除了\(x\sim y\)之间的边只需要走\(1\)次,其他边都需要走来回\(2\)次。

那如果\(x,y\)不全在这个子图中呢?那么我们就把\(x,y\)移到里面去,用\(2w-dist(x',y')\)再额外加上移动的距离即可。

为了方便操作,我们把关键点之一当作根节点,这样该子图就一定包含根节点了。

接下来,我们就可以用倍增把\(x,y\)跳到子图中,顺便计算出跳跃的距离,累加到\(2w-dist(x',y')\)中即可。

怎么求跳跃的距离呢?我们用\(dis[u][i]\)表示\(u\)节点往上\(2^i\)层的边权之和,在预处理LCA时计算出来。倍增跳跃时,每跳一次累加一下\(dis\),最终结果就是跳跃距离了。

怎么求\(dist(x,y)\)呢?根据上面的定义,\(dis[u][19]\)足以表示\(u\)到根节点的距离,那么有\(dist(x,y)=dis[x][19]+dis[y][19]-2\times dis[lca(x,y)][19]\)。
(一开始我的思路比较傻,是在倍增求LCA的过程中,每跳一步累加一次\(dis\)。这样显然不如上面优啦)

\(\texttt{<Code/>}\)

点击查看代码
#include<bits/stdc++.h>
#define N 100010
using namespace std;
int n,k,q,root,w;
struct edge{int to,w;};
vector<edge> G[N];
bool is[N];
int dep[N],fa[N][20],dis[N][20];
void dfs(int u,int father){
	dep[u]=dep[father]+1;
	fa[u][0]=father;
	for(int i=1;i<20;i++)
		fa[u][i]=fa[fa[u][i-1]][i-1],
		dis[u][i]=dis[u][i-1]+dis[fa[u][i-1]][i-1];
	for(auto i:G[u])
		if(i.to!=father){
			dis[i.to][0]=i.w;
			dfs(i.to,u);
			if(is[i.to])
				is[u]=1,
				w+=i.w;
		}
}
int lca(int u,int v){
	if(dep[u]<dep[v]) swap(u,v);
	for(int i=19;i>=0;i--)
		if(dep[fa[u][i]]>=dep[v])
			u=fa[u][i];
	if(u==v) return u;
	for(int i=19;i>=0;i--)
		if(fa[u][i]!=fa[v][i])
			u=fa[u][i],v=fa[v][i];
	return fa[u][0];
}
int dist(int u,int v){
	return dis[u][19]+dis[v][19]-2*dis[lca(u,v)][19];
}
int jump(int &x){
	int ans=0;
	for(int i=19;i>=0;i--)
		if(fa[x][i]&&!is[fa[x][i]])
			ans+=dis[x][i],
			x=fa[x][i];
	ans+=dis[x][0],x=fa[x][0];
	return ans;
}
int main(){
	cin>>n>>q>>k;
	for(int i=1;i<n;i++){
		int u,v,w;
		cin>>u>>v>>w;
		G[u].push_back({v,w});
		G[v].push_back({u,w});
	}
	for(int i=1;i<=k;i++){
		cin>>root;
		is[root]=1;
	}
	dfs(root,0);
	w*=2;
	while(q--){
		int x,y;
		cin>>x>>y;
		int ans=0;
		if(!is[x]) ans+=jump(x);
		if(!is[y]) ans+=jump(y);
		ans+=w-dist(x,y);
		cout<<ans<<"\n";
	}
	return 0;
}

标签:dist,-#,19,int,题解,P9433,fa,ans,dis
From: https://www.cnblogs.com/Sinktank/p/18239723

相关文章

  • js逆向-2-chrome开发者工具
    你真的认识浏览器吗?DevTool官方文档:ChromeDevTools | ChromeforDevelopers使用Chrome开发者工具调试和优化Web应用。https://developers.google.cn/web/tools/chrome-devtools/打开chrome开发者工具有一些网站会禁用右键检查和键盘事件,但是我们有很多方法可以打......
  • DAQmx数据采集---C++版本
    (一)效果展示:(二)采集流程:检索采集设备检索采集通道创建DAQ任务创建采集通道配置采集频率开始采集任务读取采集数据停止采集任务清空采集任务(三)相关接口:该接口可以检测系统已连接的相关采集卡的设备名称paramdata:分配的空间用来存储系统识别到的设备名称......
  • MySQL bin-log日志恢复数据
    目录一、开启二进制日志二、检查二进制日志是否开启三、使用二进制日志备份和恢复使用二进制日志备份恢复前先创建备份:应用二进制日志:扩展用法:四、常见命令和操作五.使用 mysqlbinlog 工具查看二进制日志1.查看二进制日志的内容2.解码二进制日志并将内容保存到......
  • scoop-软件包管理器
    scoopscoop官网https://scoop.sh/项目github地址https://github.com/ScoopInstaller/Scoop安装scoopSet-ExecutionPolicyRemoteSigned修改脚本执行策略Invoke-RestMethod-Urihttps://get.scoop.sh|Invoke-Expression安装scoop安装软件gitscoop及b......
  • choco-软件包管理器
    安装choco以管理员身份打开powershell$psversiontable查看powershell版本修改执行powershell脚本策略Set-ExecutionPolicyRemoteSigned安装chocoSet-ExecutionPolicyBypass-ScopeProcess-Force;[System.Net.ServicePointManager]::SecurityProtocol=[Sy......
  • 2024-06-05 拷贝、函数、装饰器、迭代生成器
    一、浅拷贝lists=[1,2,[6]]内存空间不同,浅拷贝内容不变 new_lists=copy(lists)lists.append(7)print(lists,new_lists)//[1,2,[6],7][1,2,[6]]改变列表中内容,内存空间相同,数值改变new_lists=copy(lists)lists[-1].append(7)print(lists,new_lists)//[......
  • 2024-06-06 闭包、常用函、类和实例
    一、闭包1.定义闭包是一个函数内部定义的内部函数,且可以访问外部函数的变量。常用与数据隐藏和信息封装。defhello():username='小小奇'defvoi()://内部函数变量returnusernamereturnvoi2.数据隐藏将变量封装在内部函数......
  • 周报 | 24.6.3-24.6.9文章汇总
    为了更好地整理文章和发表接下来的文章,以后每周都汇总一份周报。OpenCV与AI深度学习|实战|OpenCV实现扫描文本矫正应用与实现详解(附源码)-CSDN博客DeepDriving|多目标跟踪算法之DeepSORT-CSDN博客GiantPandaCV|提升分类模型acc(一):BatchSize&LARS-CSDN博客天才程......
  • python笔记 - 用typer开发CLI程序
    探索Typer在开发命令行界面(CLI)应用程序时,Python提供了许多优秀的库,如argparse、click等。然而,Typer作为一个相对较新的库,以其简洁性和强大的功能脱颖而出。Typer基于Click,但利用了Python的类型提示(typehints)来简化开发过程。为什么选择Typer?简洁性:通过类型提......
  • route_localnet decides whether a loopback-hosting server can server requests out
    BackgroundWhenIwasfollowingtheRAGexamplepromptflow-resource-hubtotracemyapplicationthroughapromtflowserverhostedontheloopbackinterface,asthelocalenvisavirtualmachineonAzure,andafterIaddNSGruletoallowtherequeststo......