HDU2586 LCA

本文介绍了一种用于解决给定n个点和n-1条边的独特路径问题的LCA算法。通过构建图结构并进行深度优先搜索,算法能够高效地找到任意两点之间的最近公共祖先,并计算出两点间路径的长度。

题意:给定n个点,n-1条边,每两个点之间的路独一无二

LCA

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stdlib.h>
 4 const int maxn = 40005;
 5 int head[ maxn ],cnt;
 6 struct node{
 7     int u,val,next;
 8 }edge[ maxn*2 ];
 9 int ace[ maxn ],fa[ maxn ],dis[ maxn ],deep[ maxn ];
10 void init(){
11     cnt=0;
12     memset( head,-1,sizeof( head ));
13     memset( fa,0,sizeof( fa ));
14 }
15 void addedge( int a,int b ,int c ){
16     edge[ cnt ].u=b;
17     edge[ cnt ].val=c;
18     edge[ cnt ].next=head[ a ];
19     head[ a ]=cnt++;
20 }
21 int n;
22 
23 void dfs( int now,int now_father,int now_deep,int now_dis,int now_ace ){
24     fa[ now ]=now_father;
25     deep[ now ]=now_deep;
26     dis[ now ]=now_dis;
27     deep[ now ]=now_deep;
28     for( int i=head[ now ];i!=-1;i=edge[ i ].next ){
29         int v=edge[ i ].u;
30         if( fa[ v ]==0 )
31             dfs( v,now,now_deep+1,now_dis+edge[ i ].val,now_ace );
32     }
33 }
34 
35 int find( int a,int b ){
36     if( a==b )
37         return a;
38     if( deep[ a ]>deep[ b ] )
39         return find( fa[ a ],b );
40     else 
41         return find( a,fa[ b ] );
42 }
43 
44 int main(){
45     int T;
46     scanf("%d",&T);
47     while( T-- ){
48         init();
49         int m;
50         scanf("%d%d",&n,&m);
51         int a,b,c;
52         for( int i=0;i<n-1;i++ ){
53             scanf("%d%d%d",&a,&b,&c);
54             addedge( a,b,c );
55             addedge( b,a,c );
56         }
57 
58         for( int i=1;i<=n;i++ )
59             if( fa[ i ]==0 )
60                 dfs( i,-1,0,1,i );//x,fa[x],deep,dis,ace
61 
62         while( m-- ){
63             scanf("%d%d",&a,&b);
64             if( ace[ a ]==ace[ b ] ){
65                 int k=find( a,b );
66                 printf("%d\n",dis[a]+dis[b]-2*dis[k]);
67             }
68             else
69                 printf("0\n");
70         }
71     //    printf("\n");
72     }
73     return 0;
74 }

 

转载于:https://www.cnblogs.com/xxx0624/archive/2013/02/05/2893375.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值