好像是模板题 当作练习题 不错; 要求任意两点之间的距离。可以假设一个根节点,然后所有点到根节点的距离,然后求出任意两点多公共祖先; 距离就变成了
dis[u]+dis[v] - 2*dis[ lca(u,v) ] 非常好的题目
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 8 struct date{ 9 int v,val,next; 10 }edge[112345]; 11 int N,M,total,head[112345],dis[112345]; 12 void add_edge( int u,int v,int val ){ 13 edge[total].v = v; 14 edge[total].val = val; 15 edge[total].next = head[u]; 16 head[u] = total++; 17 } 18 bool vis[112345]; int num,sta[112345],tab[112345],dep[112345],dp[112345][22]; 19 void LCA( int son,int deep,int w ){ 20 dep[num] = deep; tab[num] = son; sta[son] = num++; dis[son] = w; vis[son] = true; 21 for( int i = head[son]; i != -1; i = edge[i].next ){ 22 int v = edge[i].v; //cout<<edge[i].val<<endl; 23 if( !vis[v] ) 24 { LCA( v,deep+1,w+edge[i].val ); dep[num] = deep; tab[num] = son; num++; } 25 } 26 //dep[num] = deep; tab[num] = son; num++; 27 } 28 int work( int n1,int n2 ){ 29 if( dep[n1] < dep[n2] )return n1; 30 return n2; 31 } 32 void RMQ( ){ 33 for( int i = 1; i <= num; i++ )dp[i][0] = i; 34 for( int i = 1; (1<<i) <= num; i++ ) 35 for( int j = 1; j - 1 + (1<<i) <= num; j++ ) 36 dp[j][i] = work( dp[j][i-1],dp[j+(1<<(i-1))][i-1] ); 37 } 38 int query( int L,int R ) 39 { 40 int k = 0; 41 while( (1<<(k+1)) <= (R-L+1) )k++; 42 return tab[work( dp[L][k],dp[R-(1<<k)+1][k] )]; 43 } 44 int main( ) 45 { 46 int u,v,w; char str[3]; 47 while( scanf("%d%d",&N,&M) != EOF ) 48 { 49 memset( head,-1,sizeof(head) ); total = 0; 50 for( int i = 1; i <= M; i++ ) 51 { 52 scanf("%d%d%d%s",&u,&v,&w,&str); 53 add_edge( u,v,w ); 54 add_edge( v,u,w ); 55 } 56 memset( vis,0,sizeof(vis) ); 57 num = 1; LCA( 1,1,0 ); num--; RMQ( ); 58 //for( int i = 1; i <= num; i++ )cout<<i<<" "<<dep[i]<<" "<<tab[i]<<endl; 59 int Q; scanf("%d",&Q); 60 while( Q-- ){ 61 scanf("%d%d",&u,&v); 62 //cout<<u<<" "<<v<<" "<<dis[u]<<" "<<dis[v]<<endl; 63 if( sta[u] > sta[v] )swap( u,v ); 64 int t = query(sta[u],sta[v]);//cout<<endl<<" "<<t<<endl; 65 //cout<<t<<" "<<dis[1]<<" "<<u<<" "<<v<<" "<<dis[u]<<" "<<dis[v]<<endl; 66 cout<<dis[u]+dis[v]-2*dis[t]<<endl; 67 } 68 } 69 return 0; 70 }