zoukankan      html  css  js  c++  java
  • 【37.48%】【hdu 2587】How far away ?(3篇文章,3种做法,LCA之树上倍增)

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

    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(0k<=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

    【题解】

    设p[i][j]表示i往上走2^j个节点到达的节点。
    p[i][j]=p[p[i][j-1]][j-1];
    然后先让所求的两个点的高度一样。
    即高度高的一直往上走走到和高度底的高度一样;
    然后再一起往上走走到共同的祖先;(最近);
    找到祖先后输出dis[x]+dis[y]-2*dis[LCA];就是距离了。
    这个距离是树上的最短距离。还是很有用的。可以扩展下;

    #include <cstdio>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int MAXN = 50000;
    const int MAX = 16;
    
    vector <int> son[MAXN],w[MAXN];
    int n,p[MAXN][MAX+5],dep[MAXN],pre[MAX+5],m;
    long long dis[MAXN];
    
    void input(int &r)
    {
        char t = getchar();
        while (!isdigit(t)) t = getchar();
        r = 0;
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
    }
    
    void dfs(int x,int f)
    {
        dep[x] = dep[f] + 1;
        p[x][0] = f;
        for (int i = 1; i <= MAX; i++)
            p[x][i] = p[p[x][i - 1]][i - 1];
        int len = son[x].size();
        for (int i = 0; i <= len - 1; i++)
        {
            int y = son[x][i];
            if (y != f)
            {
                dis[y] = dis[x] + w[x][i];
                dfs(y, x);
            }
        }
    }
    
    int main()
    {
        //freopen("F:\rush.txt", "r", stdin);
        pre[0] = 1;
        for (int i = 1; i <= MAX; i++)
            pre[i] = pre[i - 1] << 1;
        int T;
        input(T);
        while (T--)
        {
            input(n); input(m);
            for (int i = 1; i <= n; i++)
                son[i].clear(),w[i].clear();
            for (int i = 1; i <= n - 1; i++)
            {
                int x, y, z;
                input(x); input(y); input(z);
                son[x].push_back(y);
                w[x].push_back(z);
                son[y].push_back(x);
                w[y].push_back(z);
            }
            dis[1] = 0;
            dfs(1, 0);
            for (int i = 1; i <= m; i++)
            {
                int t0, t1,pret0,pret1;
                input(t0); input(t1);
                pret0 = t0; pret1 = t1;
                if (dep[t0] > dep[t1])
                    swap(t0, t1);
                for (int i = MAX; i >= 0; i--)
                    if (dep[t0] <= dep[t1] - pre[i])
                        t1 = p[t1][i];
                if (t1 == t0)
                {
                    printf("%I64d
    ",dis[pret0]+dis[pret1]-2*dis[t0]);
                    continue;
                }
                for (int i = MAX; i >= 0; i--)
                {
                    if (p[t0][i] == p[t1][i])
                        continue;
                    t0 = p[t0][i], t1 = p[t1][i];
                }
                printf("%I64d
    ", dis[pret0]+dis[pret1]-2*dis[p[t0][0]]);
            }
        }
        return 0;
    }
  • 相关阅读:
    [译]:Orchard入门——媒体文件的添加与管理
    [译]:Orchard入门——给网站添加页面
    [译]:Orchard入门——给网站添加新博客
    [译]:Orchard入门——导航与菜单
    [译]:Orchard入门——构建你的第一个Orchard网站
    [译]:Orchard入门——Orchard控制面板概览
    [译]:Orchard入门——使用WebMatrix管理Orchard网站
    [译]:Orchard入门——手动安装Orchard
    [译]:Orchard入门——安装Orchard
    VS2013缺少报表工具
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632178.html
Copyright © 2011-2022 走看看