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...