【LCA倍增】POJ1330-Nearest Common Ancestors

【知识点:离线算法&在线算法】

一个离线算法,在开始时就需要知道问题的所有输入数据,而且在解决一个问题后就要立即输出结果。

一个在线算法是指它可以以序列化的方式一个个的处理输入,也就是说在开始时并不需要已经知道所有的输入。

【倍增-在线算法】

水题……这道题范围卡得很紧…数组少了一位就会WA。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<vector>
  6 using namespace std;
  7 const int MAXN=10000+10;
  8 const int DEG=20;
  9 vector<int> E[MAXN];
 10 int n;
 11 int anc[MAXN][DEG],dep[MAXN];
 12 
 13 void addedge(int u,int v)
 14 {
 15     E[u].push_back(v);
 16 }
 17 
 18 void dfs(int v,int p,int d)
 19 {
 20     anc[v][0]=p;
 21     dep[v]=d;
 22     for (int i=0;i<E[v].size();i++)
 23         dfs(E[v][i],v,d+1);
 24 }
 25 
 26 void getanc()
 27 {
 28     for (int i=1;i<DEG;i++)
 29         for (int j=1;j<=n;j++)
 30         {
 31             anc[j][i]=anc[anc[j][i-1]][i-1];
 32         }
 33 }
 34 
 35 int swim(int x,int H)
 36 {
 37     for (int i=0;H>0;i++)
 38     {
 39         if (H&1) x=anc[x][i];
 40         H/=2;
 41     }
 42     return x;
 43 }
 44 
 45 int LCA(int u,int v)
 46 {
 47     if (dep[u]<dep[v]) swap(u,v);
 48     u=swim(u,dep[u]-dep[v]);
 49     if (u==v) return u;
 50     for (int i=DEG-1;i>=0;i--)
 51     {
 52         if (anc[u][i]!=anc[v][i])
 53         {
 54             u=anc[u][i];
 55             v=anc[v][i];
 56         }
 57     }
 58     return anc[u][0];
 59 }
 60 
 61 void init()
 62 {
 63     for (int i=0;i<MAXN;i++) vector<int>().swap(E[i]);
 64     scanf("%d",&n);
 65     int notrt[MAXN];
 66     memset(notrt,0,sizeof(notrt));
 67     for (int i=0;i<n-1;i++)
 68     {
 69         int u,v;
 70         scanf("%d%d",&u,&v);
 71         addedge(u,v);
 72         notrt[v]=1;
 73     }
 74     int rt;
 75     for (int i=1;i<=n;i++) if (!notrt[i])    //这里注意下标是从1开始的
 76     {
 77         rt=i;
 78         break;
 79     }
 80     dfs(rt,0,0);
 81     getanc();
 82 }
 83 
 84 void query()
 85 {
 86     int u,v;
 87     scanf("%d%d",&u,&v);
 88     cout<<LCA(u,v)<<endl;
 89 }
 90 
 91 int main()
 92 {
 93     int T;
 94     scanf("%d",&T);
 95     for (int kase=0;kase<T;kase++)
 96     {
 97         init();
 98         query();
 99     }
100     return 0;
101 }

 【待更新】

posted @ 2016-04-12 22:34  iiyiyi  阅读(197)  评论(0编辑  收藏  举报