码迷,mamicode.com
首页 > 其他好文 > 详细

hdu2586 How far away ?(LCA->RMQ)

时间:2015-08-25 23:56:36      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:lca   rmq   

题目链接:点击打开链接

题意描述:给定一棵树,找出树中任意两点之间的距离?


解题思路:

1、dfs预处理达到欧拉序列

2、使用RMQ找出最近公共祖先

3、找出根到任意一点的距离,答案为dis[f]+dis[t]-2*dis[rt]


代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <stack>
#define MAXN 40010
using namespace std;

int head[MAXN],tol;
struct Edge{
    int to,v,next;
}edge[2*MAXN];
void addEdge(int f,int t,int v){
    edge[tol].to=t;edge[tol].v=v;edge[tol].next=head[f];head[f]=tol++;
    edge[tol].to=f;edge[tol].v=v;edge[tol].next=head[t];head[t]=tol++;
}
int e[2*MAXN],d[2*MAXN];
int fs[MAXN];
int dis[MAXN];
struct node{
    int ct,ds;
    node(int _ct,int _ds):ct(_ct),ds(_ds){}
};
stack<node> st;
bool vis[MAXN];
void dfs(int rt){
    int id=1,h=0,ds=0;
    while(!st.empty()) st.pop();
    st.push(node(rt,ds));vis[rt]=true;
    while(!st.empty()){
        node tmp=st.top();
        rt=tmp.ct;
        if(fs[rt]==-1){
            fs[rt]=id;
            dis[rt]=tmp.ds;
        }
        e[id]=rt;d[id++]=h;
        while(head[rt]!=-1&&vis[edge[head[rt]].to]) head[rt]=edge[head[rt]].next;
        if(head[rt]!=-1){
            h++;
            vis[edge[head[rt]].to]=true;
            st.push(node(edge[head[rt]].to,tmp.ds+edge[head[rt]].v));
            head[rt]=edge[head[rt]].next;
        }
        else {
            h--;
            st.pop();
        }
    }
}
int dp[MAXN*2][18];
void makeRmqIndex(int n,int b[]){
    int i,j;
    for(i=1;i<=n;i++)
        dp[i][0]=i;
    for(j=1;(1<<j)<=n;j++){
        int limit=n+1-(1<<j);
        for(i=1;i<=limit;i++)
            dp[i][j]=b[dp[i][j-1]] < b[dp[i+(1<<(j-1))][j-1]]? dp[i][j-1]:dp[i+(1<<(j-1))][j-1];
    }
}
int rmqIndex(int s,int v,int b[]){
    int k=(int)(log((v-s+1)*1.0)/log(2.0));
    return b[dp[s][k]]<b[dp[v-(1<<k)+1][k]]? dp[s][k]:dp[v-(1<<k)+1][k];
}
int n,m;
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        int f,t,v;
        tol=0;memset(head,-1,sizeof(head));
        for(int i=0;i<n-1;++i){scanf("%d%d%d",&f,&t,&v);addEdge(f,t,v);}
        memset(vis,false,sizeof(vis));
        memset(fs,-1,sizeof(fs));
        dfs(1);
        makeRmqIndex(2*n-1,d);
        for(int i=0;i<m;++i){
            scanf("%d%d",&f,&t);
            int rt;
            if(fs[f]>fs[t])///注意大小
            rt=rmqIndex(fs[t],fs[f],d);
            else
            rt=rmqIndex(fs[f],fs[t],d);
            rt=e[rt];
            printf("%d\n",dis[f]+dis[t]-2*dis[rt]);
        }
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu2586 How far away ?(LCA->RMQ)

标签:lca   rmq   

原文地址:http://blog.csdn.net/mengxingyuanlove/article/details/47984503

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!