zoukankan      html  css  js  c++  java
  • hdu 2586 How far away

    How far away ?

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 11699    Accepted Submission(s): 4300

    Problem Description
    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.
     
    Input
    First 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.
     
    Output
    For 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
     
    Source
    ECJTU 2009 Spring Contest
    一道lca入门题,题目大意是给定n户房屋,n-1条道路,询问两两房屋间的距离。我的思路是,由于是无向图,所以无固定树根,任意选节点都可。所以,先选定点1作为根,进行bfs和树上倍增。最终用距离公式dis[x]+dis[y]-2*dis[lca(x,y)]求出两房屋间的距离,其实这个公式还是蛮易懂的。不过在next这个数组名上栽了,CE滚粗。只好忍痛将next改为mnext,降低可读性。。。
    17486822    2016-07-10 21:36:39    Accepted    2586    31MS    10308K    2038B    G++    ksq2013
    hdu上测的,不知道为什么用宽搜比我的同学慢了两倍,是因为数组开太大吗???真心无语。。。
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    bool vis[80100];
    int n,bin[20],q[50100],dis[80100],deep[80100],fa[80100][20];
    int u[80100],v[80100],w[80100],first[80100],mnext[80100];
    void make_bin()
    {
        bin[0]=1;
        for(int i=1;i<=16;i++)
            bin[i]=bin[i-1]<<1;
    }
    void Init()
    {
        memset(vis,false,sizeof(vis));
        memset(fa,0,sizeof(fa));
        memset(mnext,0,sizeof(mnext));
        memset(first,0,sizeof(first));
        memset(q,0,sizeof(q));
        memset(dis,0,sizeof(dis));
        memset(deep,0,sizeof(deep));
    }
    void Link()
    {
        for(int i=1;i<=n-1;i++){
            scanf("%d%d%d",&u[i],&v[i],&w[i]);
            u[i+n-1]=v[i];v[i+n-1]=u[i];w[i+n-1]=w[i];
            mnext[i]=first[u[i]];
            mnext[i+n-1]=first[v[i]];
            first[i]=i;
            first[v[i]]=i+n-1;
        }
    }
    void bfs()
    {
        int head=0,tail=1;
        q[0]=1;vis[1]=true;
        while(head^tail){
            int now=q[head];head++;
            for(int i=1;i<=16;i++)
                if(bin[i]<=deep[now])
                    fa[now][i]=fa[fa[now][i-1]][i-1];
                else break;
            for(int i=first[now];i&&v[i]^now;i=mnext[i])
                if(!vis[v[i]]){
                    vis[v[i]]=true;
                    fa[v[i]][0]=now;
                    deep[v[i]]=deep[now]+1;
                    dis[v[i]]=dis[now]+w[i];
                    q[tail++]=v[i];
                }
        }
    }
    int lca(int x,int y)
    {
        int t=deep[x]-deep[y];
        for(int i=0;i<=16;i++)
            if(t&bin[i])
                x=fa[x][i];
        for(int i=16;i>=0;i--)
            if(fa[x][i]^fa[y][i])
                x=fa[x][i],y=fa[y][i];
        if(!(x^y))return y;
        return fa[x][0];
    }
    int main()
    {
        make_bin();
        int T;
        scanf("%d",&T);
        for(;T;T--){
            Init();
            int m;
            scanf("%d%d",&n,&m);
            Link();
            bfs();
            for(int x,y;m;m--){
                scanf("%d%d",&x,&y);
                if(deep[x]<deep[y])swap(x,y);
                printf("%d
    ",dis[x]+dis[y]-2*dis[lca(x,y)]);
            }
        }
        return 0;
    }
    



  • 相关阅读:
    go timer
    go语言函数作为参数传递
    gomail发送附件
    统计和图片来说话
    一个发邮件的demo 用golang
    Shelled-out Commands In Golang
    阅读笔记
    语言和人收藏
    在线学习网址
    通用首席娱乐官:了解自己是成功的基础
  • 原文地址:https://www.cnblogs.com/keshuqi/p/5957767.html
Copyright © 2011-2022 走看看