【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 }
【待更新】