news 2026/4/16 11:56:27

算法竞赛备考冲刺必刷题(C++) | 洛谷 P10289 小杨的旅游

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
算法竞赛备考冲刺必刷题(C++) | 洛谷 P10289 小杨的旅游

本文分享的必刷题目是从蓝桥云课洛谷AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。

欢迎大家订阅我的专栏:算法题解:C++与Python实现!

附上汇总贴:算法竞赛备考冲刺必刷题(C++) | 汇总


【题目来源】

洛谷:[P10289 GESP样题 八级] 小杨的旅游 - 洛谷

【题目描述】

小杨准备前往 B 国旅游。

B 国有n nn座城市,这n nn座城市依次以1 11n nn编号。城市之间由n − 1 n-1n1条双向道路连接,任意两座城市之间均可达(即任意两座城市之间存在可达的路径)。

小杨可以通过双向道路在城市之间移动,通过一条双向道路需要1 11单位时间。

B 国城市中有k kk座城市设有传送门。设有传送门的城市的编号依次为b 1 , b 2 , ⋯ , b k b_1,b_2, \cdots ,b_kb1,b2,,bk。小杨可以从任意一座设有传送门的城市花费0 00单位时间前往另一座设有传送门的城市。

注:如果两座设有传送门的城市之间存在双向道路,那么小杨可以选择通过双向道路移动,也可以选择通过传送门传送。

小杨计划在 B 国旅游q qq次。第i ii次旅游(1 ≤ i ≤ q 1 \le i \le q1iq),⼩杨计划从编号为u i u_iui的城市前往编号为v i v_ivi的城市,小杨希望你能求出所需要的最短时间。

【输入】

第一行包含三个正整数n , k , q n,k,qn,k,q,分别表示 B 国的城市数量,设有传送门的城市数量,以及小杨计划在 B 国旅游的次数。
接下来n − 1 n-1n1行,每行包含两个正整数x i , y i x_i, y_ixi,yi,表示一条双向道路连接的两座城市的编号。
n + 1 n + 1n+1行包含k kk个正整数,表示设有传送门的城市的编号。
接下来q qq行,每行包含两个正整数u i , v i u_i,v_iui,vi,表示小杨第i ii次旅游行程的起点城市编号与终点城市编号。

【输出】

输出共q qq行。第i ii行(1 ≤ i ≤ q 1 \leq i \leq q1iq)输出一个非负整数,表示小杨计划第i ii次旅游从编号为u i u_iui的城市前往编号为v i v_ivi的城市所需要的最短时间。

【输入样例】

7 2 1 5 7 3 6 2 3 1 5 5 4 1 2 7 4 3 7

【输出样例】

4

【算法标签】

《洛谷 P10289 小杨的旅游》 #广度优先搜索BFS# #最短路# #最近公共祖先LCA# #GESP#

【代码详解】

#include<bits/stdc++.h>usingnamespacestd;constintN=200005,M=N*2;// N: 最大节点数, M: 最大边数typedefpair<int,int>PII;// 定义pair类型,用于存储节点和步数intn,k,Q;// n: 节点数, k: 特殊节点数, Q: 查询次数inth[N],e[M],ne[M],idx;// 邻接表存储树intdep[N],dep2[N],fa[N][30];// dep: 节点深度, dep2: 到最近特殊节点的距离, fa: 倍增祖先表boolst[N];// 标记数组,用于BFS2queue<int>q;// BFS队列queue<PII>q2;// 多源BFS队列// 添加无向边voidadd(inta,intb){e[idx]=b,ne[idx]=h[a],h[a]=idx++;// 添加边a->b}// 预处理节点深度和倍增祖先表voidbfs(introot){memset(dep,0x3f,sizeof(dep));// 初始化为无穷大dep[0]=0,dep[root]=1;// 虚拟0节点深度为0, 根节点深度为1q.push(root);while(!q.empty())// 计算节点深度{intt=q.front();q.pop();for(inti=h[t];i!=-1;i=ne[i])// 遍历节点t的所有邻接点{intj=e[i];// 邻接节点jif(dep[j]>dep[t]+1)// 如果j的深度还未计算{dep[j]=dep[t]+1;// 计算j的深度q.push(j);// j入队fa[j][0]=t;// j向上走2^0=1步即为父节点tfor(intk=1;k<=29;k++)// 递推计算fa[j][k]{// j向上走2^k步等于j向上走2^(k-1)步后, 再向上走2^(k-1)步fa[j][k]=fa[fa[j][k-1]][k-1];}}}}}// LCA倍增算法,计算节点x和节点y的最近公共祖先intlca(intx,inty){if(dep[x]<dep[y])swap(x,y);// 保证x为深度较大的节点// 步骤1:把节点x向上跳,直到与节点y深度相同for(intk=29;k>=0;k--)// 从高位向低位尝试if(dep[fa[x][k]]>=dep[y])x=fa[x][k];// 如果跳2^k步后深度仍大于等于y, 就跳if(x==y)returnx;// 如果x和y已经相同, 则找到LCA// 步骤2:两个节点同时向上跳,跳到公共祖先的下一层for(intk=29;k>=0;k--){if(fa[x][k]!=fa[y][k])// 如果跳2^k步后祖先不同, 就都跳上去{x=fa[x][k];y=fa[y][k];}}returnfa[x][0];// 返回x或y的父节点, 即为最近公共祖先}// 多源BFS,计算每个节点到最近特殊节点的距离voidbfs2(){while(!q2.empty()){intu=q2.front().first;// 当前节点intstep=q2.front().second;// 到起点的距离// cout << "u step " << u << " " << step << endl;q2.pop();for(inti=h[u];i!=-1;i=ne[i])// 遍历u的所有邻接节点{intj=e[i];// 邻接节点jif(st[j])continue;// 如果j已访问,跳过dep2[j]=step+1;// 更新j到最近特殊节点的距离q2.push({j,step+1});// j入队st[j]=1;// 标记j已访问}}}intmain(){cin>>n>>k>>Q;// 输入节点数、特殊节点数、查询次数memset(h,-1,sizeof(h));// 初始化邻接表// 输入n-1条边,构建树for(inti=1;i<n;i++){intx,y;cin>>x>>y;add(x,y),add(y,x);// 添加无向边}// 初始化特殊节点for(inti=1;i<=k;i++){intx;cin>>x;// 输入特殊节点编号dep2[x]=0;// 特殊节点到自身的距离为0q2.push({x,0});// 特殊节点入队st[x]=1;// 标记特殊节点已访问}bfs(1);// 从节点1开始BFS,预处理深度和祖先表// 调试输出深度// for (int i=1; i<=n; i++)// cout << dep[i] << " ";// cout << endl;bfs2();// 多源BFS,计算每个节点到最近特殊节点的距离// 处理Q个查询while(Q--){intx,y;cin>>x>>y;// 输入查询的两个节点inttmp=lca(x,y);// 计算x和y的最近公共祖先intans;if(k!=0)// 如果有特殊节点// 两种走法的较小值:// 1. 直接走树边:x到y的距离 = dep[x] + dep[y] - 2*dep[tmp]// 2. 通过特殊节点:x到最近特殊节点的距离 + y到最近特殊节点的距离ans=min(dep[x]-dep[tmp]+dep[y]-dep[tmp],dep2[x]+dep2[y]);else// 如果没有特殊节点,只能走树边ans=dep[x]-dep[tmp]+dep[y]-dep[tmp];cout<<ans<<endl;// 输出结果}// 调试输出每个节点到最近特殊节点的距离// for (int i=1; i<=n; i++)// {// cout << dep2[i] << " ";// }// cout << endl;return0;}

【运行结果】

7 2 1 5 7 3 6 2 3 1 5 5 4 1 2 7 4 3 7 4
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/12 13:15:36

3D打印晶格结构全解析:原理、类型、实践路径与应用

晶格结构&#xff0c;正在成为新一代三维设计师的“必修课”。在过去几年&#xff0c;晶格结构在3D打印领域迅速崛起&#xff0c;已广泛应用于汽车零部件、医疗植入物、高性能跑鞋乃至登山背包等产品中。无论是轻量化设计、功能优化&#xff0c;还是外观创新&#xff0c;晶格结…

作者头像 李华
网站建设 2026/4/12 1:33:52

Z-Image-Turbo Kubernetes集群部署设想与挑战

Z-Image-Turbo Kubernetes集群部署设想与挑战 阿里通义Z-Image-Turbo WebUI图像快速生成模型 二次开发构建by科哥 运行截图 随着AI生成内容&#xff08;AIGC&#xff09;技术的快速发展&#xff0c;阿里通义Z-Image-Turbo作为一款高效、高质量的图像生成模型&#xff0c;凭借…

作者头像 李华
网站建设 2026/4/4 3:00:59

Z-Image-Turbo恐怖惊悚风:暗黑氛围营造技巧

Z-Image-Turbo恐怖惊悚风&#xff1a;暗黑氛围营造技巧 引言&#xff1a;当AI生成遇上心理恐惧——构建视觉压迫感的技术路径 在AI图像生成领域&#xff0c;日常场景、温馨宠物和风景画是常见主题。然而&#xff0c;真正考验模型表现力与提示工程深度的&#xff0c;往往是那些挑…

作者头像 李华
网站建设 2026/4/15 10:56:21

Z-Image-Turbo与油管18+内容隔离:安全生成策略

Z-Image-Turbo与油管18内容隔离&#xff1a;安全生成策略 引言&#xff1a;AI图像生成的双刃剑与内容安全挑战 随着AIGC技术的迅猛发展&#xff0c;AI图像生成模型如阿里通义Z-Image-Turbo已具备极高的创作自由度和视觉表现力。这类模型基于扩散机制&#xff08;Diffusion Mode…

作者头像 李华
网站建设 2026/4/13 22:49:00

城市大脑建设组件:MGeo提供底层地址服务能力

城市大脑建设组件&#xff1a;MGeo提供底层地址服务能力 在构建“城市大脑”这一复杂智能系统的过程中&#xff0c;空间数据治理是实现城市级感知、决策与调度的核心基础。其中&#xff0c;地址数据的标准化与实体对齐能力直接决定了交通调度、应急响应、人口流动分析等上层应…

作者头像 李华
网站建设 2026/4/16 11:24:45

数据集扩展建议:如何用M2FP生成增强样本提升训练质量

数据集扩展建议&#xff1a;如何用M2FP生成增强样本提升训练质量 &#x1f4d6; 项目背景与核心价值 在深度学习模型的训练过程中&#xff0c;高质量、多样化的数据集是决定模型性能上限的关键因素。尤其在人体解析、姿态估计、虚拟试衣等视觉任务中&#xff0c;对身体部位的…

作者头像 李华