q次询问最短距离
有一条权为0的边,假设端点a,b,要求u,v最短距离
于是求min(dis(u,v),dis(u,a)+dis(v,b),dis(u,b)+dis(v,a))即可
过程用lca实现
#include <bits/stdc++.h>
#define ls p<<1
#define print pt
#define fi first
#define rs p<<1|1
#define se second
#define ins insert
#define getchar nc
#define pb push_back
#define lread rd<ll>
#define read rd<int>
#define mk make_pair
#define pf push_front
#define lowb(x) lower_bound(x)
#define uppb(x) upper_bound(x)
#define all(a) a.begin(),a.end()
#define lwb(a,b,c) lower_bound(a,b,c)
#define upb(a,b,c) upper_bound(a,b,c)
#define mset(x,a) memset(x,a,sizeof(x))
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define per(i,l,r) for(int i=(l);i>=(r);i--)
using namespace std;
using ll = long long;
using i128 = __int128;
using ld = long double;
using pii = pair<int,int>;
using ull = unsigned long long;
using pll = pair<long long,long long>;
const int base = 1331;
const int N = 1e6 + 7;
const int M = 1e4 + 7;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const long long linf = 0x3f3f3f3f3f3f3f3f;
int dir[4][2]={1,0,0,1,-1,0,0,-1};
int dira[8][2]={{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{-1,1},{1,-1},{1,1}};
template <typename A, typename B>ostream &operator<<(ostream &os, const pair<A, B> &p){return os << '(' << p.first << ", " << p.second << ')';}
template<typename C,typename D = typename enable_if <!is_same<C, string>::value,typename C::value_type>::type>ostream &operator<<(ostream &os, const C &v){
os << '{';string sep;for (const D &x : v)os << sep << x, sep = ", ";return os << '}';}
void dbg_out(){cerr << endl;}
template <typename Head, typename... Tail>
void dbg_out(Head H, Tail... T){cerr << ' ' << H;dbg_out(T...);}
#ifndef ONLINE_JUDGE
#define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
#define dbg(...)
#endif
ll n,m;
int fa[N][32],dep[N];
vector<int>edge[N];
void dfs(int p,int far){
fa[p][0]=far;
rep(i,1,30)fa[p][i]=fa[fa[p][i-1]][i-1];
dep[p]=dep[far]+1;
for(auto c:edge[p]){
if(c==far)continue;
dfs(c,p);
}
}
int lca(int u,int v){
if(dep[u]<dep[v])swap(u,v);
per(k,30,0)if(dep[fa[u][k]]>=dep[v])u=fa[u][k];
if(u==v)return u;
per(k,30,0){
if(fa[u][k]!=fa[v][k]){
u=fa[u][k];v=fa[v][k];
}
}
return fa[u][0];
}
void solve(){
cin>>n;
rep(i,1,n-1){
int u,v;cin>>u>>v;
edge[u].pb(v);edge[v].pb(u);
}
dfs(1,0);
int q,r;cin>>q>>r;
cin>>m;
while(m--){
int x,y;cin>>x>>y;
ll dis = dep[x]+dep[y]-2*dep[lca(x,y)];
ll d1 = dep[x]+dep[q]+dep[y]+dep[r]-2*dep[lca(x,q)]-2*dep[lca(y,r)];
ll d2 = dep[x]+dep[q]+dep[y]+dep[r]-2*dep[lca(x,r)]-2*dep[lca(y,q)];
dbg(dep[x],dep[y],dep[q],dep[r],dis,d1,d2);
cout<<min({dis,d1,d2})<<"\n";
}
return ;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//cout << fixed << setprecision(3);
//cout << right << left << setw(3);
//int _; cin >> _; while(_--)
solve();
return 0;
}