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

    How far away ?



    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
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    struct Edge
    {
        int u,v,w;
        Edge(){}
        Edge(int _u,int _v,int _w):u(_u),v(_v),w(_w){}
    };
    const int N=4e4+5;
    vector<Edge>G[N];
    bool vis[N];
    int f[N][32],d[N],dis[N],n,m;
    void dfs(int u,int dep,int length)
    {
        if(vis[u])return;
        d[u]=dep;
        dis[u]=length;
        vis[u]=1;
        int len=G[u].size();
        for(int i=0;i<len;i++)
        {
            Edge e=G[u][i];
            dfs(e.v,dep+1,length+e.w);
        }
    }
    void bz()
    {
        for(int j=1;j<=30;j++)
            for(int i=1;i<=n;i++)
                f[i][j]=f[f[i][j-1]][j-1];
    }
    int query(int u,int v)
    {
        int res=0;
        if(d[u]<d[v])swap(u,v);
        int dc=d[u]-d[v];
        for(int i=0;i<30;i++)
            if(dc&(1<<i))
               res+=dis[u]-dis[f[u][i]],u=f[u][i];
        if(u==v)return res;
        for(int i=30;i>=0;i--)
            if(f[u][i]!=f[v][i])
                res+=dis[u]-dis[f[u][i]]+dis[v]-dis[f[v][i]],u=f[u][i],v=f[v][i];
        return res+dis[u]-dis[f[u][0]]+dis[v]-dis[f[v][0]];
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++)G[i].clear();
            memset(vis,0,sizeof(vis));
            for(int i=0;i<n-1;i++)
            {
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                G[u].push_back(Edge(u,v,w));
                G[v].push_back(Edge(v,u,w));
                f[v][0]=u;
            }
            dfs(1,0,0);
            bz();
            for(int i=0;i<m;i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                printf("%d
    ",query(u,v));
            }
        }
        return 0;
    }
     
  • 相关阅读:
    Android_AsyncTask
    table隔行变色【转】
    添加对WCF的调用(内网状态下)。
    【转】IDEA 2017破解 license server激活
    C# LIst去重
    框架内事务的近期发现,以后再研究
    启动、停止、删除Windows服务
    软件项目总结中的经验总结
    iis最大连接数和队列长度
    在一个千万级的数据库查寻中,如何提高查询效率?
  • 原文地址:https://www.cnblogs.com/homura/p/5717228.html
Copyright © 2011-2022 走看看