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 }

 

你可能感兴趣的:(HDU)