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

hdu 2586 How far away? (LCA模板)

时间:2014-10-05 00:01:07      阅读:267      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   ar   for   sp   div   c   on   

题意:

N个点,形成一棵树,边有长度。

M个询问,每个询问(a,b),询问a和b的距离

 

思路:

模板题,看代码。DFS预处理算出每个结点离根结点的距离。

 

注意:

qhead[maxn],而不是qhead[maxm]。

输出用%I64d,不要用%lld。

C++ RE后 尝试用 G++交。

 

代码:

struct node{
    int to,w,next,lca;
};
int const maxn = 40005;
int const maxm = 205;
int fa[maxn];
int head[maxn], qhead[maxn];
int cnt1,cnt2;
ll d[maxn];
ll res[maxm*2];
bool vis[maxn];

node edge[2*maxn];
node qedge[2*maxm];

int n,m;


int findFa(int x){
    return fa[x]==x?x:fa[x]=findFa(fa[x]);
}
inline void Addedge(int u,int v,int w){
    edge[++cnt1].w=w, edge[cnt1].to=v, edge[cnt1].next=head[u], head[u]=cnt1;
    edge[++cnt1].w=w, edge[cnt1].to=u, edge[cnt1].next=head[v], head[v]=cnt1;
}
inline void Addqedge(int u,int v){
    qedge[++cnt2].to=v, qedge[cnt2].next=qhead[u], qhead[u]=cnt2;
    qedge[++cnt2].to=u, qedge[cnt2].next=qhead[v], qhead[v]=cnt2;
}
void dfs(int u,int fa,ll w){
    d[u]=w;
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(v==fa) continue;
        dfs(v,u,w+edge[i].w);
    }
}
void Tarjan_LCA(int u){
    fa[u]=u, vis[u]=true;
    for(int i=head[u];i!=-1;i=edge[i].next){
        if(!vis[edge[i].to]){ //防止访问到父亲
            Tarjan_LCA(edge[i].to);
            fa[edge[i].to]=u;
        }
    }
    for(int i=qhead[u];i!=-1;i=qedge[i].next){
        if(vis[qedge[i].to]){
            qedge[i].lca=findFa(qedge[i].to);
            res[i]=d[u]+d[qedge[i].to]-2*d[qedge[i].lca];
        }
    }
}
void init(){
    rep(i,1,n) fa[i]=i;
    mem(head,-1);  mem(qhead,-1);  mem(vis,false);  mem(d,0);  mem(res,0);
    cnt1=cnt2=0;
}

int T,a,b,w;
int main(){
    cin>>T;
    while(T--){
        scanf("%d%d",&n,&m);
        init();
        rep(i,1,n-1){
            scanf("%d%d%d",&a,&b,&w);;
            Addedge(a,b,w);
        }
        rep(i,1,m){
            scanf("%d%d",&a,&b);
            Addqedge(a,b);
        }
        dfs(1,-1,0);
        Tarjan_LCA(1);
        for(int i=1;i<=cnt2;i+=2){
            if(res[i])
                printf("%I64d\n",res[i]);
            else
                printf("%I64d\n",res[i+1]);
        }
    }
}

 

hdu 2586 How far away? (LCA模板)

标签:style   blog   color   ar   for   sp   div   c   on   

原文地址:http://www.cnblogs.com/fish7/p/4006426.html

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