推荐几个博客:https://www.cnblogs.com/JVxie/p/4854719.html Tarjan离线算法的基本思路及其算法实现
https://blog.csdn.net/shahdza/article/details/7779356 LCA题集
http://www.cnblogs.com/zhouzhendong/p/7256007.html LCA的三种算法介绍
模板(题):
1.(POJ1470)http://poj.org/problem?id=1470
Tarjan离线算法
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 using namespace std; 6 const int maxn=1010; 7 const int maxm=500010; 8 struct Edge{ 9 int to,nxt; 10 }edge[maxn*2]; 11 struct Query{ 12 int q,nxt; 13 int index; 14 }query[maxm*2]; 15 int f[maxn],anc[maxn]; 16 bool vis[maxn]; 17 int head[maxn],tot; 18 int ans[maxm],h[maxm],tt,Q; 19 bool flag[maxn]; 20 int num[maxn]; 21 22 int find(int x) 23 { 24 if ( f[x]==-1 ) return x; 25 return f[x]=find(f[x]); 26 } 27 28 void merge(int x,int y) 29 { 30 int fx=find(x); 31 int fy=find(y); 32 if ( fx!=fy ) f[fx]=fy; 33 } 34 35 void addedge(int u,int v) 36 { 37 edge[tot].to=v; 38 edge[tot].nxt=head[u]; 39 head[u]=tot++; 40 } 41 42 void addquery(int u,int v,int index) 43 { 44 query[tt].q=v; 45 query[tt].nxt=h[u]; 46 query[tt].index=index; 47 h[u]=tt++; 48 query[tt].q=u; 49 query[tt].nxt=h[v]; 50 query[tt].index=index; 51 h[v]=tt++; 52 } 53 54 void init() 55 { 56 tot=0; 57 memset(head,-1,sizeof(head)); 58 tt=0; 59 memset(h,-1,sizeof(h)); 60 memset(vis,false,sizeof(vis)); 61 memset(f,-1,sizeof(f)); 62 memset(anc,0,sizeof(anc)); 63 } 64 65 void LCA(int u) 66 { 67 anc[u]=u; 68 vis[u]=true; 69 for ( int i=head[u];i!=-1;i=edge[i].nxt ) 70 { 71 int v=edge[i].to; 72 if ( vis[v] ) continue; 73 LCA(v); 74 merge(u,v); 75 anc[find(u)]=u; 76 } 77 for ( int i=h[u];i!=-1;i=query[i].nxt ) 78 { 79 int v=query[i].q; 80 if ( vis[v] ) ans[query[i].index]=anc[find(v)]; 81 } 82 } 83 84 int main() 85 { 86 int n,u,v,k; 87 while ( scanf("%d",&n)!=EOF ) 88 { 89 init(); 90 memset(flag,false,sizeof(flag)); 91 for ( int i=1;i<=n;i++ ) 92 { 93 scanf("%d:(%d)",&u,&k); 94 while ( k-- ) 95 { 96 scanf("%d",&v); 97 flag[v]=true; 98 addedge(u,v); 99 addedge(v,u); 100 } 101 } 102 scanf("%d",&Q); 103 for ( int i=0;i<Q;i++ ) 104 { 105 char ch; 106 cin>>ch; 107 scanf("%d %d)",&u,&v); 108 addquery(u,v,i); 109 } 110 int root; 111 for ( int i=1;i<=n;i++ ) 112 { 113 if ( !flag[i] ) 114 { 115 root=i; 116 break; 117 } 118 } 119 LCA(root); 120 memset(num,0,sizeof(num)); 121 for ( int i=0;i<Q;i++ ) num[ans[i]]++; 122 for ( int i=1;i<=n;i++ ) 123 { 124 if ( num[i]>0 ) printf("%d:%d\n",i,num[i]); 125 } 126 } 127 return 0; 128 }