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

    There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B"? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path("simple" means you can't visit a place twice) between every two houses. Yout task is to answer all these curious people.

    InputFirst line is a single integer T(T<=10), indicating the number of test cases. 
      For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n. 
      Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.OutputFor each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.Sample Input

    2
    3 2
    1 2 10
    3 1 15
    1 2
    2 3
    
    2 2
    1 2 100
    1 2
    2 1

    Sample Output

    10
    25
    100
    100

    给你一棵树,树上的边有权值,问你连点之间距离多少?LCA的模板题,试一下模板,顺带加深理解。
    dis(a,b)=dis(a,根)+dis(b,根)-2*dis( lca(a,b) , 根)
    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn=44000;
    int t,n,q;
    int dis[maxn],dep[maxn],que[maxn];
    int p[maxn];
    bool vis[maxn];
    int fa[maxn][50];
    struct node
    {
        int to,dis;
        node(int t,int d):to(t),dis(d){}
    };
    vector <node> e[maxn];
    void init ()
    {
        for (int i=0;i<n;++i)
            e[i].clear();
        memset(dis,0,sizeof dis);
        memset(dep,0,sizeof dep);
        memset(que,0,sizeof que);
    }
    void bfs (int x)
    {
        memset(vis,false,sizeof vis);
        int w=1,r=1;
        que[1]=x;
        dep[x]=0;
        dis[x]=0;
        p[x]=-1;
        vis[x]=true;
        while (w<=r){
            int u=que[w];w++;
            for (int i=0;i<e[u].size();++i){
                int v=e[u][i].to;
                if (vis[v]) continue;
                p[v]=u;
                vis[v]=true;
                dep[v]=dep[u]+1;
                dis[v]=dis[u]+e[u][i].dis;
                que[++r]=v;
            }
        }
    }
    void getfa ()
    {
        for (int j=0;(1<<j)<=n;++j){
            for (int i=1;i<=n;++i)
                fa[i][j]=-1;
        }
        for (int i=1;i<=n;++i){
            fa[i][0]=p[i];
        }
        for (int j=1;(1<<j)<=n;++j){
            for (int i=1;i<=n;++i)
                if (fa[i][j]!=-1)
                fa[i][j]=fa[fa[i][j-1]][j-1];
        }
    }
    int findlca (int x,int y)
    {
        if (dep[x]<dep[y]) swap(x,y);
        while (dep[x]>dep[y]){
            int j=0;
            while (dep[fa[x][j]]>dep[y]) ++j;
            if (dep[fa[x][j]]==dep[y]){x=fa[x][j];break;}//这行很容易忘!!!!
            x=fa[x][j-1];
        }
        if (x==y) return y;
        while (x!=y){
            int j=0;
            while (fa[x][j]!=fa[y][j]&&fa[x][j]!=-1) ++j;
            if (j==0)
                break;
            x=fa[x][j-1];
            y=fa[y][j-1];
        }
        return fa[x][0];
    }
    int main()
    {
        //freopen("de.txt","r",stdin);
        scanf("%d",&t);
        //printf("t=%d
    ",t);
        while (t--){
            init();
            scanf("%d",&n);
            scanf("%d",&q);
            //printf("n= %d
    ",n);
            for (int i=0;i<n-1;++i){
                int x,y,d;
                scanf("%d%d%d",&x,&y,&d);
                e[x].push_back(node(y,d));
                e[y].push_back(node(x,d));
            }
            bfs(1);
            getfa();
            for (int i=0;i<q;++i){
                int x,y;
                scanf("%d%d",&x,&y);
                //printf("%d %d
    ",x,y);
                int LCA=findlca(x,y);
                printf("%d
    ",dis[x]+dis[y]-2*dis[LCA]);
            }
        }
        return 0;
    }
  • 相关阅读:
    10 个你需要了解的 Linux 网络和监控命令
    U盘安装 bt5
    SpringCloud RabbitMQ 使用
    两个大数相乘笔试题目
    activemq 话题模式(三)
    activemq 队列模式(二)
    activemq 安装 (一)
    安装mysql5.7时缺少my.ini文件
    linux 远程rsa 登录配置 文件 /etc/ssh/sshd_config
    java -jar 解决占用终端问题
  • 原文地址:https://www.cnblogs.com/agenthtb/p/6659216.html
Copyright © 2011-2022 走看看