您的位置:首页 > 其它

hdoj 2586 How far away ? 【LCA转RMQ入门题】

2015-08-09 11:05 381 查看

How far away ?

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 8693 Accepted Submission(s): 3044

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



题意:给你一个N个点的树和Q次查询,每次查询问你任意两点间距离。

LCA转RMQ 点这里:点我

思路:<u, v>距离 = dist[ u ] + dist[ v ] - 2 * dist[ LCA(u,v)]。其中dist存储节点到根的距离。

AC代码:注意手动开栈 。。。

#pragma comment(linker, "/STACK:1024000000,1024000000") 
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 40000+100
#define MAXM 100000+1000
#define LL long long
using namespace std;
struct Edge
{
    int from, to, val, next;
};
Edge edge[MAXM];
int head[MAXN], edgenum;
int vs[MAXN<<1];
int depth[MAXN<<1];
int id[MAXN];
int dfs_clock;
int dist[MAXN];
int N, Q;
void init()
{
    edgenum = 0;
    memset(head, -1, sizeof(head));
}
void addEdge(int u, int v, int w)
{
    Edge E = {u, v, w, head[u]};
    edge[edgenum] = E;
    head[u] = edgenum++;
}
void getMap()
{
    int a, b, c;
    for(int i = 1; i < N; i++)
    {
        scanf("%d%d%d", &a, &b, &c);
        addEdge(a, b, c), addEdge(b, a, c);
    }
}
void DFS(int u, int fa, int d)
{
    id[u] = dfs_clock;
    vs[dfs_clock] = u;
    depth[dfs_clock++] = d;
    for(int i = head[u]; i != -1; i = edge[i].next)
    {
        int v = edge[i].to;
        if(v == fa) continue;
        dist[v] = dist[u] + edge[i].val;
        DFS(v, u, d+1);
        vs[dfs_clock] = u;
        depth[dfs_clock++] = d;
    }
}
void find_depth()
{
    memset(id, 0, sizeof(id));
    memset(vs, 0, sizeof(vs));
    memset(depth, 0, sizeof(depth));
    memset(dist, 0, sizeof(dist));
    dfs_clock = 1;
    DFS(1, -1, 0);
}
int dp[MAXN<<1][30];
void RMQ_init(int NN)
{
    for(int i = 1; i <= NN; i++)
        dp[i][0] = i;
    for(int j = 1; (1<<j) <= NN; j++)
    {
        for(int i = 1; i + (1<<j) - 1 <= NN; i++)
        {
            int a = dp[i][j-1];
            int b = dp[i + (1<<(j-1))][j-1];
            if(depth[a] <= depth[b])
                dp[i][j] = a;
            else
                dp[i][j] = b;
        }
    }
}
int query(int L, int R)
{
    int k = 0;
    while((1<<(k+1)) <= R-L+1) k++;
    int a = dp[L][k];
    int b = dp[R - (1<<k) + 1][k];
    if(depth[a] <= depth[b])
        return a;
    else
        return b;
}
int LCA(int u, int v)
{
    int x = id[u];
    int y = id[v];
    if(x < y)
        return vs[query(x, y)];
    else
        return vs[query(y, x)];
}
void solve()
{
    int a, b;
    while(Q--)
    {
        scanf("%d%d", &a, &b);
        printf("%d\n", dist[a] + dist[b] - 2 * dist[LCA(a, b)]);
    }
}
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d", &N, &Q);
        init();
        getMap();
        find_depth();
        RMQ_init(dfs_clock - 1);
        solve();
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: