1 해설
-
0
自动搬运
来自洛谷,原作者为

Furina
芙宁娜太可爱啦!| 青雀太可爱啦! | 题单 592617搬运于
2025-08-24 22:56:35,当前版本为作者最后更新于2024-04-04 18:35:17,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意简述:
无。
题解:
看完题目之后,我们首先要考虑一个问题:什么时候要用到传送门?
对于树上的两个点 和 ,如果不考虑传送门的话,最短距离就是这两个点到它们的最近公共祖先的距离和。
那么如果用传送门更优,那么肯定满足这一个条件: 到它最近的传送门距离加上 到它最近的传送门距离小于 和 到它们的最近公共祖先的距离和。
大家可以自己验证一些普通和特殊情况,此处就不给出证明了。
那么我们就可以先求出每个点到最近的传送门距离 ,对于询问,再输出 $\min(op_x+op_y,dep_x-dep_{lca(x,y)}+dep_y-dep_{lca(x,y)})$。
那么就可以写代码了。
注意:
- 可能没有传送门(代码中注释 A)。
代码如下:
#include<bits/stdc++.h> #define N 200100 #define I_love_Furina return//发电+放抄袭(?) #define forever 0 #define foreverr 1 #define int long long using namespace std; int n,T,m,q,head[N],op[N],num,f[N][20],dep[N]; struct node{int to,nxt;}a[N*2]; inline void add(int u,int v){a[++num].to=v,a[num].nxt=head[u],head[u]=num;} inline void solve(){//求最近传送阵距离 queue<int> q; for(int i=1,x;i<=m;i++)cin>>x,q.push(x),op[x]=0;//把所有的传送阵位置压入队列,跑bfs while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];i;i=a[i].nxt){ int v=a[i].to; if(op[v]!=-1)continue;//避免重复遍历 op[v]=op[u]+1,q.push(v); } } I_love_Furina ; } void dfs(int x,int fa){ f[x][0]=fa,dep[x]=dep[fa]+1; for(int i=1;i<=19&&f[f[x][i-1]][i-1];i++)f[x][i]=f[f[x][i-1]][i-1];//计算祖宗 for(int i=head[x];i;i=a[i].nxt)if(a[i].to!=fa)dfs(a[i].to,x); I_love_Furina ; } inline int lca(int x,int y){//求最近公共祖先 if(dep[x]<dep[y])swap(x,y); for(int i=19;i>=0;i--)if(dep[f[x][i]]>=dep[y])x=f[x][i]; if(x==y)I_love_Furina x; for(int i=19;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i]; I_love_Furina f[x][0];//注意,是返回x的父亲 } signed main(){ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin>>n>>m>>q; for(int i=1,u,v;i<n;i++)cin>>u>>v,add(u,v),add(v,u),op[i]=op[i+1]=-1; dfs(1,0),solve();//跑lca和最近传送阵距离 while(q--){ int x,y; cin>>x>>y; int LCA=lca(x,y); //cout<<lca(x,y)<<" "<<op[x]<<" "<<op[y]<<endl; cout<<min(dep[x]-dep[LCA]+dep[y]-dep[LCA],(op[x]==-1||op[y]==-1?3156781267:op[x]+op[y]))<<endl;//A:防止输出-2 } I_love_Furina forever; }完结撒花咯(点个赞再走)。
- 1
정보
- ID
- 9992
- 시간
- 1000ms
- 메모리
- 512MiB
- 난이도
- 4
- 태그
- 제출 기록
- 0
- 맞았습니다.
- 0
- 아이디