zoukankan      html  css  js  c++  java
  • hdu2586 lca倍增法

    倍增法加了边的权值,bfs的时候顺便把每个点深度求出来即可

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    #define maxn 40005
    #define DEG 20
    struct Edge{
        int to,next,w;
    }edge[maxn*2];
    int head[maxn],tot;
    void addedge(int u,int v,int w){
        edge[tot].to=v;
        edge[tot].next=head[u];
        edge[tot].w=w;
        head[u]=tot++;
    }
    int fa[maxn][DEG];
    int deg[maxn],depth[maxn];
    int flag[maxn];
    void bfs(int root){
        queue<int> que;
        deg[root]=0;depth[root]=0;
        fa[root][0]=root;
        que.push(root);
        while(!que.empty()){
            int tmp=que.front();que.pop();
            for(int i=1;i<DEG;i++)
                fa[tmp][i]=fa[fa[tmp][i-1]][i-1];
            for(int i=head[tmp];i!=-1;i=edge[i].next){
                int v=edge[i].to;
                if(v==fa[tmp][0])continue;
                deg[v]=deg[tmp]+1;
                depth[v]=depth[tmp]+edge[i].w;
                fa[v][0]=tmp;
                que.push(v);
            }
        }
    }
    int lca(int u,int v){
        if(deg[u]>deg[v]) swap(u,v);
        int hu=deg[u],hv=deg[v],tu=u,tv=v;
        for(int det=hv-hu,i=0;det;det>>=1,i++)
            if(det&1) tv=fa[tv][i];
        if(tu==tv) return tu;
        for(int i=DEG-1;i>=0;i--){
            if(fa[tu][i]==fa[tv][i]) continue;
            tu=fa[tu][i];tv=fa[tv][i];
        }
        return fa[tu][0];
    }
    void init(){
        tot=0;
        memset(flag,0,sizeof flag);
        memset(head,-1,sizeof head);
        memset(deg,0,sizeof deg);
        memset(depth,0,sizeof depth);
    }
    int main(){
        int T,n,q,u,v,w;
        cin >> T;
        while(T--){
            init();
            scanf("%d%d",&n,&q);
            for(int i=1;i<n;i++){
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w);
                addedge(v,u,w);
                flag[v]=1;
            }
            int root;
            for(int i=1;i<=n;i++) if(!flag[i]){root=i;break;}
            bfs(root);
            
            while(q--){
                scanf("%d%d",&u,&v);
                int tmp=lca(u,v);
                printf("%d
    ",depth[u]+depth[v]-2*depth[tmp]);
            }
        }
        return 0;
    }
  • 相关阅读:
    【Auto.js images.matchTemplate() 函数的特点】
    Jquery动态bind绑定已有函数,函数自动执行的问题解决方法
    浅谈javascript的运行机制
    Git
    下拉框的点击事件
    点击其他区域菜单消失
    Chrome 中的 JavaScript 断点设置和调试技巧
    前端编辑工具有感
    我的jsonp跨域问题
    浅谈Json和jsonp
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10015363.html
Copyright © 2011-2022 走看看