A 小A的最短路 LCA用欧拉序列转化为 RMQ 问题 求树上两点距离

 

分析

x y 两点的距离,可以看作它们到根节点的距离 - 2 * 它们的最近公共祖先到根节点的距离

t1 ,t2 之间不需要时间,所以题目要求的是 x-y ,t1-x+t2-y,t1-y+t2-x三条链,哪条链最短

求欧拉序,将深度看作到根节点的距离,用st数组找出它们的根节点,再套用 下面的公式 就可以了

dep[a] + dep[b] - 2 * dep[t];


//-------------------------代码----------------------------

//#define int ll
const int N = 3e5+10,M = N * 2;
int n,m;
int e[M],ne[M],w[M],h[N],idx;
// int cnt,first[N],b[M];

void add(int a,int b,int c) {
    e[idx] = b,ne[idx] = h[a],w[idx] = c,h[a] = idx ++ ;
}

int dep[N],first[N],step;
int a[M];

void dfs(int u,int fa) {
    first[u] = ++ step;
    a[step] = u;
    for(int i = h[u];~i;i=ne[i]) {
        int son = e[i];
        if(son == fa) continue;
        dep[son] = dep[u] + w[i];
        dfs(son,u);
        a[++step] = u;
//         db(step);
    }
}

int f[M][30];

void init() {
    int m = (int)(log(1.0*step) / log(2.0));
    for(int j = 0;j<=m;j++) {
        for(int i = 1;i + (1<<j) - 1<= step;i ++ ) {
            if(!j) f[i][j] = a[i];
            else {
                f[i][j] = dep[f[i][j-1]] < dep[f[i+(1<<j-1)][j-1]] ? f[i][j-1]: f[i+(1<<j-1)][j-1];
            }
        }
    }
}

int st_find(int l,int r) {
    int len=(int) (log(1.0*(r-l+1))/log(2.0));
    return dep[f[l][len]] < dep[f[r - (1 << len) + 1][len]] ? f[l][len] : f[r - (1 << len) + 1][len]; 
}

int lca(int u,int v) {
    if(first[u] > first[v]) swap(u,v);
    return st_find(first[u],first[v]);
}

int dist(int a,int b) {
    int t = lca(a,b);
    return dep[a] + dep[b] - 2 * dep[t];
}

void solve()
{
//    cin>>n>>m;
    cin>>n;
    ms(h,-1);
    fo(i,1,n-1) {
        int u,v;cin>>u>>v;
        if(i != n)add(u,v,1);
        else add(u,v,0);
    }
    int t1,t2;
    cin>>t1>>t2;
//     db(step);
    dfs(1,-1);
    init();
//     dbb(step,n*2);
    int q;cin>>q;
    while(q -- ) {
        int x,y;cin>>x>>y;
        printf("%d\n",min(min(dist(x,t1)+dist(t2,y),dist(x,t2)+dist(t1,y)),dist(x,y)));

    }
}

signed main(){
    AC();
    clapping();TLE;
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
//    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

posted @ 2022-08-05 21:20  er007  阅读(23)  评论(0编辑  收藏  举报