PKU1986+LCA

wa的代码。。纯dfs

 1 /*
 2 LCA
 3 */
 4 #include<stdio.h>
 5 #include<string.h>
 6 #include<stdlib.h>
 7 #include<algorithm>
 8 #include<iostream>
 9 #include<queue>
10 #include<map>
11 #include<math.h>
12 #pragma comment(linker, "/STACK:16777216")
13 using namespace std;
14 typedef long long ll;
15 //typedef __int64 int64;
16 const int maxn = 40005;
17 const int inf = 0x7fffffff;
18 const double pi=acos(-1.0);
19 const double eps = 1e-8;
20 
21 int dis[ maxn ],ace[ maxn ],deep[ maxn ],fa[ maxn ];
22 int cnt,head[ maxn ];
23 struct node{
24     int u,next,val;
25 }edge[ maxn<<4 ];
26 void init(){
27     cnt = 0;
28     memset( head,-1,sizeof( head ) );
29     memset( fa,0,sizeof( fa ) );
30 }
31 void addedge( int a,int b,int c ){
32     edge[ cnt ].u = b;
33     edge[ cnt ].val = c;
34     edge[ cnt ].next = head[ a ];
35     head[ a ] = cnt++;
36 }
37 int find( int x,int y ){
38     if( x==y ) return x;
39     if( deep[ x ]>deep[ y ] ) return find( fa[x],y );
40     else return find( x,fa[y] );
41 }
42 void dfs( int now,int now_father,int now_ace,int now_deep,int now_dis ){
43     fa[ now ] = now_father;
44     ace[ now ] = now_ace;
45     deep[ now ] = now_deep;
46     dis[ now ] = now_dis;
47     for( int i=head[ now ];i!=-1;i=edge[ i ].next ){
48         int v = edge[ i ].u;
49         if( fa[ v ]==0 ){
50             dfs( v,now,now_ace,now_deep+1,now_dis+edge[ i ].val );
51         }
52     }
53 }
54 int main(){
55     int n,m;
56     scanf("%d%d",&n,&m);
57         int a,b,c;
58         char s[2];
59         init();
60         while( m-- ){
61             scanf("%d%d%d%s",&a,&b,&c,s);
62             addedge( a,b,c );
63             addedge( b,a,c );
64         }
65         for( int i=1;i<=n;i++ ){
66             if( fa[i]==0 ){
67                 dfs( i,-1,i,0,0 );
68             }
69         }
70         int k;
71         scanf("%d",&k);
72         while( k-- ){
73             scanf("%d%d",&a,&b);
74             int father = find( a,b );
75             printf("%d\n",dis[a]+dis[b]-2*dis[father]);
76         
77         }
78     
79     return 0;
80 }
View Code

tarjan算法。。

 1 /*
 2 LCA+tarjan
 3 计算一棵树中任意两点之间的距离
 4 */
 5 #include<stdio.h>
 6 #include<string.h>
 7 #include<algorithm>
 8 #include<math.h>
 9 using namespace std;
10 const int maxn = 40005;
11 int dis[ maxn ],vis[ maxn ],fa[ maxn ];
12 struct node{
13     int u,next,val;
14 }edge[ maxn<<2 ],ex_edge[ maxn ];
15 int cnt,head[ maxn ],ex_cnt,ex_head[ maxn ];
16 int ans[ maxn ];
17 
18 void init(){
19     cnt = ex_cnt = 0;
20     memset( head,-1,sizeof( head ) );
21     memset( ex_head,-1,sizeof( ex_head ) );
22     memset( vis,0,sizeof( vis ) );
23     memset( fa,-1,sizeof( fa ) );
24     memset( dis,0,sizeof( dis ) );
25 }
26 
27 void addedge( int a,int b,int c ){
28     edge[ cnt ].u = b;
29     edge[ cnt ].val = c;
30     edge[ cnt ].next = head[ a ];
31     head[ a ] = cnt++;
32 }
33 void ex_addedge( int a,int b,int c ){
34     ex_edge[ ex_cnt ].u = b;
35     ex_edge[ ex_cnt ].val = c;
36     ex_edge[ ex_cnt ].next = ex_head[ a ];
37     ex_head[ a ] = ex_cnt++;
38 }
39 
40 int find( int x ){
41     if( fa[x]==-1 ) return x;
42     fa[x] = find( fa[x] );
43     return fa[x];
44 }
45 
46 void tarjan( int u,int dist ){
47     vis[ u ] = 1;
48     dis[ u ] = dist;
49     for( int i=ex_head[ u ];i!=-1;i=ex_edge[ i ].next ){
50         int v = ex_edge[ i ].u;
51         if( vis[ v ]==1 ){
52             ans[ ex_edge[ i ].val ] = dis[ u ]+dis[ v ]-2*dis[ find(v) ];
53         }
54     }
55     for( int i=head[ u ];i!=-1;i=edge[ i ].next ){
56         int v = edge[ i ].u;
57         if( vis[v]==0 ){
58             tarjan( v,dist+edge[ i ].val );
59             fa[ v ] = u;
60         }
61     }
62 }
63 
64 int main(){
65     int n,m;
66     while( scanf("%d%d",&n,&m)==2 ){
67         int a,b,c;
68         char s[2];
69         init();
70         for( int i=0;i<m;i++ ){
71             scanf("%d%d%d%s",&a,&b,&c,s);
72             addedge( a,b,c );
73             addedge( b,a,c );
74         }
75         int k;
76         scanf("%d",&k);
77         for( int i=0;i<k;i++ ){
78             scanf("%d%d",&a,&b);
79             ex_addedge( a,b,i );
80             ex_addedge( b,a,i );
81         }
82         tarjan( 1,0 );//因为这是一棵树 任选1为root,tarjan( i,dis ):表示i到root的距离为dis
83         for( int i=0;i<k;i++ ){
84             printf("%d\n",ans[i]);
85         }
86     }
87     return 0;
88 }
View Code
原文地址:https://www.cnblogs.com/xxx0624/p/3093785.html