HDU2874 LCA

题意:给定一张图,包括n个城市,m条路径,q个询问( 图中没有环 )。

bfs会超时!!

LCA问题:询问 a,b 之间的最短距离。因为图中不可能出现环,所以两点之间有且仅有一条路,或者没有。

所以先预处理出a,b的最近公共祖先,和他们各自的距离。

比如a,b的最近公共祖先为father(简易图)

aa----father----b

             |

             |

            a1

             |

              a

ans=dis[ a ]+dis[ b ]-dis[ father ]*2;

dfs中的fa==0判断是因为这是无向图。。。谨记。。。这只是求距离,对父子关系要求不明显

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stdlib.h>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn = 10005;
 7 const int maxm = maxn;
 8 int head[ maxn ],cnt;
 9 struct node{
10     int from,to,val,next;
11 }edge[ maxm<<2 ];
12 int deep[ maxn ],dis[ maxn ],fa[ maxn ];
13 int ace[ maxn ];//最近公共祖先
14 int n,m,q;
15 void init(){
16     memset( head,-1,sizeof( head ));
17     cnt=0;
18     memset( fa,0,sizeof( fa ));
19 }
20 void addedge( int a,int b,int c ){
21     edge[ cnt ].from=a;
22     edge[ cnt ].to=b;
23     edge[ cnt ].next=head[ a ];
24     edge[ cnt ].val=c;
25     head[ a ]=cnt++;
26 }
27 
28 int find( int x,int y ){
29     if( x==y ) return x;
30     if( deep[ x ]>deep[ y ] )
31         return find( fa[ x ],y );
32     else 
33         return find( x,fa[ y ] );
34 }
35 
36 void dfs( int now,int now_father,int now_ace,int now_deep,int now_dis ){
37     fa[ now ]=now_father;
38     deep[ now ]=now_deep;
39     dis[ now ]=now_dis;
40     ace[ now ]=now_ace;
41     for( int i=head[ now ];i!=-1;i=edge[ i ].next ){
42         int v=edge[ i ].to;
43         if( fa[ v ]==0 )
44             dfs( v,now,now_ace,now_deep+1,now_dis+edge[ i ].val );
45     }
46 }
47 
48 int main(){
49     while( scanf("%d%d%d",&n,&m,&q)==3 ){
50         int a,b,c;
51         init();
52         while( m-- ){
53             scanf("%d%d%d",&a,&b,&c);
54             addedge( a,b,c );
55             addedge( b,a,c );
56         }
57         for( int i=1;i<=n;i++ ){
58             if( fa[ i ]==0 ){
59                 dfs( i,-1,i,0,1 );
60             }
61         }
62         while( q-- ){
63             scanf("%d%d",&a,&b);
64             if( ace[ a ]==ace[ b ] ){
65                 int father=find( a,b );
66                 printf("%d\n",dis[ a ]+dis[ b ]-2*dis[ father ]);
67             }
68             else printf("Not connected\n");
69         }
70     }
71     return 0;
72 }
keep moving...
原文地址:https://www.cnblogs.com/xxx0624/p/2892188.html