zoukankan      html  css  js  c++  java
  • hdu 2586 How far away? (LCA模板)

    题意:

    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
    ",res[i]);
                else
                    printf("%I64d
    ",res[i+1]);
            }
        }
    }
  • 相关阅读:
    ORM数据库框架 SQLite ORMLite MD
    ORM数据库框架 greenDAO SQLite MD
    layer-list shape drawable 层叠背景 MD
    BAT 批处理 特殊符号 总结 [MD]
    集合 enum 枚举 简介 案例 [MD].md
    Gradle 翻译 ProGuard Shrink 混淆和压缩 [MD]
    构建配置 Enable multidex
    构建配置 defaultConfig signingConfigs buildTypes productFlavors dependencies
    Android 资源混淆 AndResGuard MD
    Android 第三方加固方案 对比 打包 [MD]
  • 原文地址:https://www.cnblogs.com/fish7/p/4006426.html
Copyright © 2011-2022 走看看