首先假设我们不考虑 u 和 v 两点的缆车,那么 x 和 y 之间的路程就是 x 和 y 的深度减去他们的 lca 的深度。

接下来我们考虑使用缆车,无非也就两种情况:

  • x -> u -> v -> y
  • x -> v -> u -> y

我们对上面三种情况取一个 min 就行了。

加快读的话可以跑到 600 ms

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;
const int maxn = 301110;
const int M = 1e9+7;
int n,q,xx,yy;

vector<int> v[maxn];

int sz[maxn],fa[maxn],d[maxn],son[maxn];

void dfs1(int u,int pre)
{
    sz[u] = 1;fa[u] = pre;d[u] = d[pre]+1;
    for(auto i : v[u])
    {
        if(i == pre) continue;
        dfs1(i,u);
        sz[u] += sz[i];
        if(sz[son[u]] < sz[i]) son[u] = i;
    }
}

int top[maxn],idx;

void dfs2(int u,int t)
{
    top[u] = t;
    if(!son[u]) return;
    dfs2(son[u],t);
    for(auto i : v[u])
    {
        if(i == fa[u] || i == son[u]) continue;
        dfs2(i,i);
    }
}

int lca(int x,int y)
{
    for(;top[x] != top[y];d[top[x]]>d[top[y]]?x=fa[top[x]]:y=fa[top[y]]);
    return d[x]<d[y]?x:y;       //在一条链上了
}

int dis(int x,int y)
{
    return d[x]+d[y]-2*d[lca(x,y)];
}

signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);
    cin>>n;
    int x,y;
    for(int i = 1; i < n; i++)
    {
        cin>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs1(1,1);dfs2(1,1);
    cin>>xx>>yy;
    cin>>q;
    while(q--)
    {
        cin>>x>>y;
        int ans = dis(x,y);
        ans = min(ans,dis(x,xx)+dis(y,yy));
        ans = min(ans,dis(x,yy)+dis(y,xx));
        cout<<ans<<endl;
    }
    return 0;
}