• 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;
    }
    



  • 相关阅读:
    使用ServiceStackRedis链接Redis简介
    浅谈SQL SERVER中事务的ACID
    Sql Server查询性能优化之走出索引的误区
    Redis命令总结
    TSQL查询进阶—理解SQL Server中的锁
    SQL Server 2005 分区表实践——分区切换
    SQL Server Profiler 模板
    深入浅出SQL Server中的死锁
    不同的单元中的类可以共用同一个命名空间
    从硬盘上装xp手记(2005.8.14 )
  • 原文地址:https://www.cnblogs.com/keshuqi/p/5957767.html
Copyright © 2020-2023  润新知