Tarjan-LCA HDU2586 How far away ?

How far away ?

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


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
 
 
学模板
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int cases,n,q;
 7 int a,b,c;
 8 struct data{
 9     int next,to,dis;
10 }edge[100010];
11 int cnt,head[50010],father[50010],w[50010];
12 bool check[50010];
13 void add_edge(int start,int end,int d){
14     edge[++cnt].next=head[start];
15     edge[cnt].to=end;
16     edge[cnt].dis=d;
17     head[start]=cnt;
18 }
19 struct dt{
20     int nt,t,num;
21 }eg[40010];
22 int ct,hd[20010],lca[20010];
23 void add_ask(int start,int end,int nm){
24     eg[++ct].nt=hd[start];
25     eg[ct].t=end;
26     eg[ct].num=nm;
27     hd[start]=ct;    
28 }
29 int find(int x){ 
30     if(x!=father[x]) father[x]=find(father[x]);
31     return father[x];
32 }
33 void dfs(int u){
34     check[u]=1;
35     father[u]=u;
36     for(int i=hd[u];i;i=eg[i].nt)
37         if(check[eg[i].t]) lca[eg[i].num]=find(eg[i].t);
38     for(int i=head[u];i;i=edge[i].next)
39         if(!check[edge[i].to]){
40             w[edge[i].to]=w[u]+edge[i].dis;
41             dfs(edge[i].to);
42             father[edge[i].to]=u;
43         }
44 }
45 int main(){
46     scanf("%d",&cases);
47     for(int tt=1;tt<=cases;tt++){
48         memset(check,0,sizeof(check));
49         memset(head,0,sizeof(head));
50         memset(hd,0,sizeof(hd));
51         memset(edge,0,sizeof(edge));
52         memset(eg,0,sizeof(eg));
53         memset(father,0,sizeof(father));
54         memset(lca,0,sizeof(lca));
55         memset(w,0,sizeof(w));
56         ct=0;
57         cnt=0;
58         scanf("%d%d",&n,&q);
59         for(int i=1;i<n;i++){
60             scanf("%d%d%d",&a,&b,&c);
61             add_edge(a,b,c);
62             add_edge(b,a,c);    
63         }
64         for(int i=1;i<=q;i++){
65             scanf("%d%d",&a,&b);
66             add_ask(a,b,i);
67             add_ask(b,a,i);
68         }
69         dfs(1);
70         for(int i=1;i<=2*q;i+=2){
71             a=eg[i].t;
72             b=eg[i+1].t;
73             c=eg[i].num;
74             printf("%d\n",w[a]+w[b]-2*w[lca[c]]);
75         }
76     }
77     return 0;
78 }

 

转载于:https://www.cnblogs.com/sdfzxh/p/7008899.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值