hdu 2586 How far away ?【LCA】

来源:互联网 发布:php 判断时间大小 编辑:程序博客网 时间:2024/06/11 00:15


How far away

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

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

 

 思路来源:http://blog.csdn.net/mengxiang000000/article/details/51437842


 AC代码:

#include<stdio.h>#include<string.h>#include<vector>using namespace std;int head[100000];int f[100000];int qhead[100000];int vis[100000];int dir[100000];int problem[100000][2];struct EdgeNode{    int from;    int to;    int w;    int lca;    int next;} e[100000],q[100000];int n,m,ask,cont;int find(int a){    int r=a;    while(f[r]!=r)        r=f[r];    int i=a;    int j;    while(i!=r)    {        j=f[i];        f[i]=r;        i=j;    }    return r;}void merge(int a,int b){    int A,B;    A=find(a);    B=find(b);    if(A!=B)        f[B]=A;}void add(int from,int to,int w){    e[cont].from=from;    e[cont].to=to;    e[cont].w=w;    e[cont].next=head[from];    head[from]=cont;    cont++;    e[cont].from=to;    e[cont].to=from;    e[cont].w=w;    e[cont].next=head[to];    head[to]=cont;    cont++;}void addq(int from,int to){    q[cont].from=from;    q[cont].to=to;    q[cont].lca=-1;    q[cont].next=qhead[from];    qhead[from]=cont;    cont++;    q[cont].from=to;    q[cont].to=from;    q[cont].lca=-1;    q[cont].next=qhead[to];    qhead[to]=cont;    cont++;}void LCA(int u){    f[u]=u;    vis[u]=1;    for(int k=head[u]; k!=-1; k=e[k].next)    {        int to=e[k].to;        if(vis[to]==0)        {            int w=e[k].w;            dir[to]=dir[u]+w;            LCA(to);            merge(u,to);        }    }    for(int k=qhead[u]; k!=-1; k=q[k].next)    {        int to=q[k].to;        if(vis[to]==1)        {            q[k].lca=find(to);            q[k^1].lca=q[k].lca;        }    }}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        cont=0;        for(int i=1; i<=n; i++)f[i]=i;        memset(vis,0,sizeof(vis));        memset(head,-1,sizeof(head));        memset(qhead,-1,sizeof(qhead));        memset(dir,0,sizeof(dir));        for(int i=0; i<n-1; i++)        {            int x,y,w;            scanf("%d%d%d",&x,&y,&w);            add(x,y,w);        }        cont=0;        int tot=0;        for(int i=0; i<m; i++)        {            int x,y;            scanf("%d%d",&x,&y);            addq(x,y);        }        LCA(1);        for(int i=0; i<m; i++)        {            int tmp=i*2,u=q[tmp].from,v=q[tmp].to,lca=q[tmp].lca;            printf("%d\n",dir[u]+dir[v]-2*dir[lca]);        }    }}















0 0