hdu 2586 How far away ? 带权lca

How far away ?

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

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

ECJTU 2009 Spring Contest

思路:在lca的基础上加dis(距离根的距离)数组,在dfs处理好,ans=dis[a]-2*dis[LCA(a,b)]+dis[b];

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
#define true ture
#define false flase
using namespace std;
#define ll long long
#define inf 0xfffffff
int scan()
{
    int res = 0 , ch ;
    while( !( ( ch = getchar() ) >= ‘0‘ && ch <= ‘9‘ ) )
    {
        if( ch == EOF )  return 1 << 30 ;
    }
    res = ch - ‘0‘ ;
    while( ( ch = getchar() ) >= ‘0‘ && ch <= ‘9‘ )
        res = res * 10 + ( ch - ‘0‘ ) ;
    return res ;
}
#define maxn 40010
#define M 22
struct is
{
    int v,next,w;
} edge[maxn*2];
int deep[maxn],jiedge;
int dis[maxn];
int head[maxn];
int rudu[maxn];
int fa[maxn][M];
void add(int u,int v,int w)
{
    jiedge++;
    edge[jiedge].v=v;
    edge[jiedge].w=w;
    edge[jiedge].next=head[u];
    head[u]=jiedge;
}
void dfs(int u)
{
    for(int i=head[u]; i; i=edge[i].next)
    {
        int v=edge[i].v;
        int w=edge[i].w;
        if(!deep[v])
        {
            dis[v]=dis[u]+edge[i].w;
            deep[v]=deep[u]+1;
            fa[v][0]=u;
            dfs(v);
        }
    }
}
void st(int n)
{
    for(int j=1; j<M; j++)
        for(int i=1; i<=n; i++)
            fa[i][j]=fa[fa[i][j-1]][j-1];
}
int LCA(int u , int v)
{
    if(deep[u] < deep[v]) swap(u , v) ;
    int d = deep[u] - deep[v] ;
    int i ;
    for(i = 0 ; i < M ; i ++)
    {
        if( (1 << i) & d )  // 注意此处,动手模拟一下,就会明白的
        {
            u = fa[u][i] ;
        }
    }
    if(u == v) return u ;
    for(i = M - 1 ; i >= 0 ; i --)
    {
        if(fa[u][i] != fa[v][i])
        {
            u = fa[u][i] ;
            v = fa[v][i] ;
        }
    }
    u = fa[u][0] ;
    return u ;
}
void init()
{
    memset(head,0,sizeof(head));
    memset(fa,0,sizeof(fa));
    memset(rudu,0,sizeof(rudu));
    memset(deep,0,sizeof(deep));
    jiedge=0;
}
int main()
{
    int x,n;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        init();
        scanf("%d%d",&n,&x);
        for(int i=1; i<n; i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
            rudu[v]++;
        }
        for(int i=1;i<=n;i++)
        {
            if(!rudu[i])
            {
                deep[i]=1;
                dis[i]=0;
                dfs(i);
                break;
            }
        }
        st(n);
        while(x--)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            printf("%d\n",dis[a]-2*dis[LCA(a,b)]+dis[b]);
        }
    }
    return 0;
}

时间: 2024-10-08 10:17:10

hdu 2586 How far away ? 带权lca的相关文章

hdu 2874 Connections between cities 带权lca判是否联通

Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, some mat

hdu 2586 How far away ?倍增LCA

hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增求取LCA,同时跟新距离数组 因为 \(2^{16} > 40000\) 所以所以表示祖先的数组dp[][]第二维取到16即可 就这道题来说,与比较tarjan比较,稍快一点 代码: #include <iostream> #include <algorithm> #includ

HDU 2586 How far away ? (离线LCA Tarjan算法模板)

How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6422    Accepted Submission(s): 2411 Problem Description There are n houses in the village and some bidirectional roads connecting

hdu 3074 Zjnu Stadium (带权并查集)

Zjnu Stadium Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1744    Accepted Submission(s): 660 Problem Description In 12th Zhejiang College Students Games 2007, there was a new stadium built i

HDU 2818 Building Block(带权并查集)

[题目链接]:Click here~~ [题意]: 给 n 块砖头,开始各为一堆,两种操作: 1.把 X 所在的那一堆箱子里的砖头放到 Y 所在的那一堆上面. 2.询问 X 下面有多少块砖. [解题思路]:好像大家都叫它带权并查集,那为了方便,这里也这样叫吧,因为涉及前面的和后面的箱子个数,对应的查找操作,一开始想用结构体来写,在结构体里定义每个箱子的前驱和后继,每次输入的时候统计一下相应的前驱和后继的个数,后来发现不行,因为涉及到合并操作,比如说M 2 4 M 2 6连续出现两个2,用结构体是

HDU 4359 Easy Tree DP? 带权二叉树的构造方法 dp

题意: 给定n deep 1.构造一个n个节点的带权树,且最大深度为deep,每个节点最多只能有2个儿子 2.每个节点的值为2^0, 2^1 ··· 2^(n-1)  任意两个节点值不能相同 3.对于一个节点,若他有左右儿子,则左子树的和 < 右子树的和 问: 有多少种构造方法. 思路: dp #include <stdio.h> #include <iostream> #include <algorithm> #include <cstring> u

HDU 2586 How far away ?(LCA模板 近期公共祖先啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 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

HDU 2586 How far away ?(LCA在线算法实现)

http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给出一棵树,求出树上任意两点之间的距离. 思路: 这道题可以利用LCA来做,记录好每个点距离根结点的距离,然后只要计算出两点的LCA,这样一来答案就是distance[u]+distance[v]-2distance[LCA]. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #includ

HDU 2586 How far away ?(LCA模板 最近公共祖先啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 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