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

    How far away ?

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


    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
     
    Recommend
    lcy
    看样子是不能用floyd

     对于无向图可以随便取一个点当作根节点

    先求一遍从根节点到其它节点的距离

    然后lca  看代码叭

    #include <iostream>
    #include <cstdio>
    #include <sstream>
    #include <cstring>
    #include <map>
    #include <cctype>
    #include <set>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <cmath>
    #include <bitset>
    #define rap(i, a, n) for(int i=a; i<=n; i++)
    #define rep(i, a, n) for(int i=a; i<n; i++)
    #define lap(i, a, n) for(int i=n; i>=a; i--)
    #define lep(i, a, n) for(int i=n; i>a; i--)
    #define rd(a) scanf("%d", &a)
    #define rlld(a) scanf("%lld", &a)
    #define rc(a) scanf("%c", &a)
    #define rs(a) scanf("%s", a)
    #define rb(a) scanf("%lf", &a)
    #define rf(a) scanf("%f", &a)
    #define pd(a) printf("%d
    ", a)
    #define plld(a) printf("%lld
    ", a)
    #define pc(a) printf("%c
    ", a)
    #define ps(a) printf("%s
    ", a)
    #define MOD 2018
    #define LL long long
    #define ULL unsigned long long
    #define Pair pair<int, int>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define _  ios_base::sync_with_stdio(0),cin.tie(0)
    //freopen("1.txt", "r", stdin);
    using namespace std;
    const int maxn = 110000, INF = 0x7fffffff;
    int n, m, s;
    int anc[maxn][20], deep[maxn], vis[maxn];
    LL d[maxn];
    int head[maxn], cnt;
    struct node
    {
        int u, v, next, c;
    }Node[maxn << 1];
    
    void add_(int u, int v, int c)
    {
        Node[cnt].u = u;
        Node[cnt].v = v;
        Node[cnt].c = c;
        Node[cnt].next = head[u];
        head[u] = cnt++;
    }
    
    void add(int u, int v, int  c)
    {
        add_(u, v, c);
        add_(v, u, c);
    }
    
    int dfs(int u, int fa)
    {
        for(int i = 1; i < 20; i++)
            anc[u][i] = anc[anc[u][i - 1]][i - 1];
        for(int i = head[u]; i != -1; i = Node[i].next)
        {
            int v = Node[i].v;
            if(v == fa || deep[v]) continue;
            anc[v][0] = u;
            deep[v] = deep[u] + 1;
            dfs(v, u);
        }
    }
    
    int lca(int u, int v)
    {
        if(deep[u] < deep[v]) swap(u, v);
        for(int i = 20 - 1; i >= 0; i--)
            if(deep[anc[u][i]] >= deep[v])
                u = anc[u][i];
    
        for(int i = 20 - 1; i >= 0; i--)
        {
            if(anc[u][i] != anc[v][i])
            {
                u = anc[u][i];
                v = anc[v][i];
            }
        }
        if(u == v) return u;
        return anc[u][0];
    }
    
    
    
    void spfa()
    {
        for(int i = 0; i < maxn; i++) d[i] = INF;
       // cout<< d[2] << endl;
        deque<int> Q;
        Q.push_back(s);
        d[s] = 0;
        vis[s] = 1;
        while(!Q.empty())
        {
            int u = Q.front(); Q.pop_front();
            vis[u] = 0;
            for(int i = head[u]; i != -1; i = Node[i].next)
            {
                int v = Node[i].v;
               // cout << v << endl;
                if(d[v] > d[u] + Node[i].c)
                {
                    //cout << 2222 << endl;
                    d[v] = d[u] + Node[i].c;
                    if(!vis[v])
                    {
                        if(Q.empty()) Q.push_front(v);
                        else if(d[Q.front()] > d[v]) Q.push_front(v);
                        else Q.push_back(v);
                        vis[v] = 1;
                    }
                }
            }
        }
    }
    
    
    
    void init()
    {
        mem(head, -1);
        cnt = 0;
        mem(vis, 0);
        mem(anc, 0);
        mem(deep, 0);
    }
    
    int main()
    {
    
        int T;
        rd(T);
        while(T--)
        {
            init();
            rd(n), rd(m);
            s = 1;
            for(int i = 1; i < n; i++)
            {
                int u, v, w;
                rd(u), rd(v), rd(w);
                add(u, v, w);
            }
            spfa();
            deep[s] = 1;
            dfs(s, -1);
            for(int i = 0; i < m; i++)
            {
                int u, v;
                rd(u), rd(v);
                int x = lca(u, v);
                printf("%d
    ", d[u] + d[v] - 2 * d[x]);
    
            }
    
    
    
        }
    
    
        return 0;
    }
  • 相关阅读:
    11. Container With Most Water
    9. Palindrome Number
    375. 猜数字大小 II leetcode java
    leetcode 72 编辑距离 JAVA
    73. 矩阵置零 leetcode JAVA
    快速排序 JAVA实现
    63. 不同路径 II leetcode JAVA
    重写(override)与重载(overload)
    62 不同路径 leetcode JAVA
    leetcode 56 合并区间 JAVA
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/10744211.html
Copyright © 2011-2022 走看看