先不看线缆,会发现,直接用lca求最短路就行了
加上线缆,就多加一个判断即可
比如询问x到y,线缆是j到k
在dis(x,y),dis(x,j)+dis(k,y),dis(x,k)+dis(j,y)这三个中取最小
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <cmath>
#define ll long long
#define pi 3.1415927
#define inf 0x3f3f3f3f
#define mod 1000000007
using namespace std;
#define _int __int128_t
inline int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0',c=getchar();
return f*x;
}
void print(int x)
{
if(x < 0) {putchar('-');x = -x;}
if(x/10) print(x/10);
putchar(x%10+'0');
}
int n,m,head[1000005],dep[1000005],f[1000005][30],tot;
struct node{
int to,next;
}edge[1000005];
void add(int u, int v)
{
edge[++tot].to=v;
edge[tot].next=head[u];
head[u]=tot;
}
void dfs(int u, int father)
{
dep[u]=dep[father]+1;
for(int i=1;i<=20;i++)
f[u][i]=f[ f[u][i-1] ][i-1];
for(int i=head[u]; i ;i=edge[i].next){
if(edge[i].to==father)
continue;
f[edge[i].to][0]=u;
dfs(edge[i].to,u);
}
}
int lca(int x, int y)
{
if(dep[x]<dep[y])
swap(x,y);
for (int i = 20; i >= 0; i--)
if (dep[f[x][i]] >= dep[y])
x=f[x][i];
if(x==y)
return x;
for(int i=20;i>=0;i--){
if(f[x][i]!=f[y][i]){
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
int disc(int x, int y)
{
return dep[x]+dep[y]-2*dep[lca(x,y)];
}
int main ()
{
int T,i,t,j,k,p,sum=0;
n=read();
for(i=1;i<n;++i){
int u=read(),v=read();
add(u,v);
add(v,u);
}
dfs(1,0);
j=read(); k=read();
int q=read();
for(i=1;i<=q;++i){
int x=read(),y=read();
int ans=disc(x,y);
ans=min(ans,disc(x,j)+disc(k,y));
ans=min(ans,disc(x,k)+disc(j,y));
printf("%d\n",ans);
}
return 0;
}
京公网安备 11010502036488号