倍增法求最近公共祖先 笔记与思路整理
作者:互联网
核心为二维father数组:father[i][j]存储第i个点向上跳2^j次到达的点
如father[i][0]表示点i的父亲,
[i][1]表示i向上两层,
[i][2]表示i向上四层。
用一次DFS维护father数组以及dep等等。
详解见函数主体:
int LCA(int x, int y){ if(dep[x] < dep[y])swap(x,y); //保证x深于y int t = dep[x] - dep[y]; //t为x跳到y同一深度所需步数 for(int i = 0 ; i <= 20 ; i++) if( (1<<i) & t) x = father[x][i]; //1左移i次按位与t可得出t在二进制下第i位上是否为1 //若为1则将x向上跳2^i位,整个循环后正好跳了t位 if(x == y)return x;//是否y为x祖先,即跳到同一高度时已经相等 for(int i = 20 ; i >= 0 ; i--){ //x和y同时向上跳 if(father[x][i] == father[y][i])continue; //若x和y跳2^i位后已经相等,则跳多了至少一位,不跳这一步 x = father[x][i]; y = father[y][i]; //x和y向上跳2^i位后尚未相等,则跳2^i位 } //跳完后x与y应该处于“刚好没相等”的层数,即在其最近公共祖先下一层 return father[x][0]; //返回其父亲即为最近公共祖先 }
标签:向上,int,位后,father,笔记,dep,祖先,倍增,法求 来源: https://www.cnblogs.com/miserweyte/p/11362026.html