C++ P3379 【模板】最近公共祖先(LCA)
阿新 • • 發佈:2018-11-11
早就想寫LCA了,奈何沒有dfs基礎,先做了最小生成樹
廢話就說到這裡,上程式碼。
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; const int maxn=500000+2; int n,m,s; int k=0; int head[maxn],d[maxn],p[maxn][21]; struct Node{ int v,next; }e[maxn*2]; void add(int u,int v){ e[k].v=v; e[k].next=head[u]; head[u]=k++; } void dfs(int u,int fa){//預處理 d[u]=d[fa]+1; p[u][0]=fa; for(int i=1;(1<<i)<=d[u];i++){ p[u][i]=p[p[u][i-1]][i-1]; } for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; if(v!=fa){ dfs(v,u); } } } int lca(int a,int b){ if(d[a]>d[b])swap(a,b); for(int i=20;i>=0;i--) if(d[a]<=d[b]-(1<<i))b=p[b][i]; if(a==b)return a; for(int i=20;i>=0;i--) if(p[a][i]==p[b][i])continue; else a=p[a][i],b=p[b][i]; return p[a][0]; } int main(){ memset(head,-1,sizeof(head)); int a,b; scanf("%d%d%d",&n,&m,&s); for(int i=0;i<n-1;i++){ scanf("%d%d",&a,&b); add(a,b); add(b,a); } dfs(s,0); for(int i=1;i<=m;i++){ scanf("%d%d",&a,&b); int ans=lca(a,b); printf("%d\n",ans); } return 0; }
為什麼沒有註釋呢?因為我把程式碼背過了。
所以還是分享一下我背程式碼的經驗吧。
- 背程式碼之前請找一個大佬講一下這個演算法,讓你大概瞭解演算法的執行過程(
其實就是半懂不懂)!! - 一句一句的背,不要貪快
- 一個程式碼塊一個程式碼塊的背,比如賦值一部分 迴圈一部分,最終一個方法一個方法的背
另外,十分感謝gzh大佬為我們講解了LCA演算法QAQ