zoukankan      html  css  js  c++  java
  • poj1986带权lca

    lca求距离,带权值 的树上求lca,我是用倍增法求的,求两点之间的距离转化为到根节点之间的距离

    (de了一个小时 的bug,重打居然就过了。。。。)

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cassert>
    #include<iomanip>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    
    using namespace std;
    
    const double g=10.0,eps=1e-7;
    const int N=400000+10,maxn=500+100,inf=0x3f3f3f;
    
    struct edge{
        int to,Next,w;
    }e[N];
    int head[N],dis[N];
    int cnt,depth[N],father[20][N];
    void add(int u,int v,int w)
    {
        e[cnt].to=v;
        e[cnt].w=w;
        e[cnt].Next=head[u];
        head[u]=cnt++;
    }
    void dfs(int u,int f)
    {
        father[0][u]=f;
        for(int i=head[u];~i;i=e[i].Next)
        {
            int To=e[i].to;
            if(To!=f)
            {
                depth[To]=depth[u]+1;
                dis[To]=dis[u]+e[i].w;
                dfs(To,u);
            }
        }
    }
    void init(int n)
    {
        depth[1]=1;
        dfs(1,-1);
        for(int i=1;i<20;i++)
            for(int j=1;j<=n;j++)
               father[i][j]=father[i-1][father[i-1][j]];
    }
    int lca(int x,int y)
    {
        if(depth[x]>depth[y])swap(x,y);
        for(int i=0;i<20;i++)
            if((depth[y]-depth[x])>>i&1)
               y=father[i][y];
        if(x==y)return x;
        for(int i=19;i>=0;i--)
        {
            if(father[i][x]!=father[i][y])
            {
                x=father[i][x];
                y=father[i][y];
            }
        }
        return father[0][x];
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n,m;
        cin>>n>>m;
        cnt=0;
        memset(head,-1,sizeof head);
        for(int i=0;i<m;i++)
        {
            int a,b,c;
            string s;
            cin>>a>>b>>c>>s;
            add(a,b,c);
            add(b,a,c);
        }
        init(n);
        int k;
        cin>>k;
        while(k--){
            int a,b;
            cin>>a>>b;
            int p=lca(a,b);
            cout<<dis[a]+dis[b]-2*dis[p]<<endl;
        }
        return 0;
    }
    /********************
    7 6
    1 6 13 E
    6 3 9 E
    3 5 7 S
    4 1 3 N
    2 4 20 W
    4 7 2 S
    5
    1 6
    6 1
    1 4
    4 1
    2 6
    ********************/
    View Code
  • 相关阅读:
    关于数组的算法-编程之美读后感-1
    java学习笔记之线程1
    java学习笔记之IO一()
    java学习笔记之泛型
    java学习笔记之正则表达式
    Thinking in java学习笔记之String的不可变性
    Thinking in java学习笔记之map的应用
    Thinking in java学习笔记之set
    scrapy之中间件
    Linux之Redis-redis哨兵集群详解
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7246768.html
Copyright © 2011-2022 走看看