推荐几个博客: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 }
POJ1470

相关文章: