码迷,mamicode.com
首页 > 其他好文 > 详细

lca 最近公共祖先

时间:2015-05-14 23:22:22      阅读:258      评论:0      收藏:0      [点我收藏+]

标签:

http://poj.org/problem?id=1330

 

 

技术分享
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define mt(a,b) memset(a,b,sizeof(a))
  5 using namespace std;
  6 const int inf=0x3f3f3f3f;
  7 class LCA { ///最近公共祖先 build_o(n*logn) query_o(1)
  8     typedef int typec;///边权的类型
  9     static const int ME=2e4+10;///边的个数
 10     static const int MV=1e4+10;///点的个数
 11     static const int MR=MV<<1;///rmq的个数
 12     struct E {
 13         int v,next;
 14         typec w;
 15     } e[ME];
 16     int le,head[MV],H[MV],dex[MR],aa[MR],bb[MR],raa[MR][20],rbb[MR][20],Index;
 17     typec dist[MV];
 18     void init_dex() {
 19         dex[0]=-1;
 20         for(int i=1; i<MR; i++) {
 21             dex[i]=dex[i>>1]+1;
 22         }
 23     }
 24     void dfs(int u,int fa,int level) {
 25         aa[Index]=u;
 26         bb[Index++]=level;
 27         for(int i=head[u]; ~i; i=e[i].next) {
 28             int v=e[i].v;
 29             if(v==fa) continue;
 30             dist[v]=dist[u]+e[i].w;
 31             dfs(v,u,level+1);
 32             aa[Index]=u;
 33             bb[Index++]=level;
 34         }
 35     }
 36 public:
 37     LCA() { init_dex();};
 38     void init() {
 39         le=Index=0;
 40         mt(head,-1);
 41     }
 42     void add(int u,int v,typec w) {
 43         e[le].v=v;
 44         e[le].w=w;
 45         e[le].next=head[u];
 46         head[u]=le++;
 47     }
 48     void build(int root) {
 49         dist[root]=0;
 50         dfs(root,-1,0);
 51         mt(H,-1);
 52         mt(rbb,0x3f);
 53         for(int i=0; i<Index; i++) {
 54             int tmp=aa[i];
 55             if(H[tmp]==-1) H[tmp]=i;
 56             rbb[i][0]=bb[i];
 57             raa[i][0]=aa[i];
 58         }
 59         for(int i=1; (1<<i)<=Index; i++) {
 60             for(int j=0; j+(1<<i)<Index; j++) {
 61                 int next=j+(1<<(i-1));
 62                 if(rbb[j][i-1]<=rbb[next][i-1]) {
 63                     rbb[j][i]=rbb[j][i-1];
 64                     raa[j][i]=raa[j][i-1];
 65                 } else {
 66                     rbb[j][i]=rbb[next][i-1];
 67                     raa[j][i]=raa[next][i-1];
 68                 }
 69             }
 70         }
 71     }
 72     int query(int l,int r) {
 73         l=H[l];
 74         r=H[r];
 75         if(l>r) swap(l,r);
 76         int p=dex[r-l+1];
 77         r-=(1<<p)-1;
 78         return rbb[l][p]<=rbb[r][p]?raa[l][p]:raa[r][p];
 79     }
 80     typec getdist(int l,int r) {
 81         return dist[l]+dist[r]-2*dist[query(l,r)];
 82     }
 83 } gx;
 84 
 85 const int M=1e4+10;
 86 int du[M];
 87 int main() {
 88     int t,n,u,v;
 89     while(~scanf("%d",&t)) {
 90         while(t--) {
 91             scanf("%d",&n);
 92             gx.init();
 93             mt(du,0);
 94             for(int i=1; i<n; i++) {
 95                 scanf("%d%d",&u,&v);
 96                 du[v]++;
 97                 gx.add(u,v,1);
 98                 gx.add(v,u,1);
 99             }
100             int rt=1;
101             for(int i=1; i<=n; i++) {
102                 if(du[i]==0) {
103                     rt=i;
104                     break;
105                 }
106             }
107             gx.build(rt);
108             scanf("%d%d",&u,&v);
109             printf("%d\n",gx.query(u,v));
110         }
111     }
112     return 0;
113 }
View Code

 

 

 

end

lca 最近公共祖先

标签:

原文地址:http://www.cnblogs.com/gaolzzxin/p/4504692.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!