zoukankan      html  css  js  c++  java
  • hdu 2586 How far away ?[LCA/ST+RMQ]

    题目链接

    题意:

    给你一棵树,让你求出树上的两个点之间的距离。

    思路:

    用LCA解决,求出两个节点到根节点的距离减去两倍的LCA到根节点的距离

    #include "bits/stdc++.h"
    using namespace std;  
    const int maxn = 40010;   
    int dp[2*maxn][30];   
    bool vis[maxn];  
    int ver[2*maxn], dept[2*maxn];
    int first[maxn], dis[maxn];  
    struct edge {
        int u,v,w,next;  
    } e[2*maxn];  
    int cnt,head[maxn];  
    int num;
    void add(int u ,int v ,int w) {
        e[num].u = u; e[num].v = v; e[num].w = w;  
        e[num].next = head[u]; head[u] = num++;  
    }   
    void dfs(int u ,int dep) {
        vis[u] = true; ver[++cnt] = u; first[u] = cnt; dept[cnt] = dep;  
        for(int i = head[u]; i != -1; i = e[i].next) { 
            if(!vis[e[i].v]) {
                int v = e[i].v , w = e[i].w;  
                dis[v] = dis[u] + w;  
                dfs(v,dep+1);  
                ver[++cnt] = u; dept[cnt] = dep;  
            }
        }          
    }  
    void ST(int n) {
        for(int i = 1; i <= n; i++) dp[i][0] = i;  
        for(int j = 1; (1<<j) <= n; j++) {
            for(int i = 1; i+(1<<j)-1 <= n; i++) {
                int a = dp[i][j-1], b = dp[i+(1<<(j-1))][j-1];  
                dp[i][j] = dept[a] < dept[b]?a:b;  
            }  
        }  
    }  
    int RMQ(int l,int r) {
        int k=0;  
        while((1<<(k+1)) <= r-l+1) k++;  
        int a = dp[l][k], b = dp[r-(1<<k)+1][k];   
        return dept[a] < dept[b]?a:b;  
    }  
    int LCA(int u ,int v) {
        int x = first[u] , y = first[v];  
        if(x > y) swap(x,y);  
        int res = RMQ(x,y);  
        return ver[res];  
    }  
    int main(int argc, char const *argv[])
    {
        int T;  
        scanf("%d", &T);  
        while(T--) {
            int n, q;
            num = 0;  
            scanf("%d%d", &n, &q);  
            memset(head, -1, sizeof(head));  
            memset(vis, false, sizeof(vis));  
            for(int i=1; i<n; i++) {
                int u,v,w;  
                scanf("%d%d%d",&u,&v,&w);  
                add(u,v,w);  
                add(v,u,w);
            }  
            cnt = 0; dis[1] = 0;  
            dfs(1,1);
            ST(2*n-1);  
            while(q--) {
                int u,v;  
                scanf("%d%d",&u,&v);  
                int lca = LCA(u,v);  
                printf("%d
    ",dis[u] + dis[v] - 2*dis[lca]);  
            }  
        }  
        return 0;  
    }  
    

      

  • 相关阅读:
    【NOIP2007】守望者的逃离
    20200321(ABC)题解 by 马鸿儒 孙晨曦
    20200320(ABC)题解 by 王一帆
    20200319(ABC)题解 by 王一帆 梁延杰 丁智辰
    20200314(ABC)题解 by 董国梁 蒋丽君 章思航
    20200309(ABC)题解 by 梁延杰
    20200307(DEF)题解 by 孙晨曦
    20200306(ABC)题解 by 孙晨曦
    20200305(DEF)题解 by 孙晨曦
    20200303(ABC)题解 by 王锐,董国梁
  • 原文地址:https://www.cnblogs.com/cniwoq/p/7237828.html
Copyright © 2011-2022 走看看