• 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;
    }
     
  • 相关阅读:
    Shell 丢弃错误和输出信息
    awk 循环过滤EPC脚本
    Tornado 异步浅解
    返回顶部
    Tornado 的安全性保障机制Cookie XSRF跨站请求伪造阻断 &用户验证机制
    Nginxre quest_time 和upstream_response_time
    Tornado WEB服务器框架 Epoll-- 【Mysql数据库】
    Tornado WEB服务器框架 Epoll-- 【模板】
    常见的SQL等价改写
    redis配置信息详解
  • 原文地址:https://www.cnblogs.com/homura/p/5717228.html
Copyright © 2020-2023  润新知