倍增法LCA

#include
using namespace std;
int n,q,a,b,rt,dsu[40][100],dep[100];
vector g[10005];
void dfs(int v,int p,int d){				//预处理深搜用邻接表打好父亲数组与深度数组
    dsu[0][v]=p;					//记录父亲数组,当前V结点往上走2^0步即为其父亲
    dep[v]=d;						//记录深度数组
    for(int i=0;idep[v])swap(u,v);
    for(int k=0;k<32;k++)
        if(dep[v]-dep[u]>>k&1)//这里解释一下,由运算符优先级等价于((dep[v]-dep[u])>>k)&1
            v=dsu[k][v];//目标就是把dep[v]-dep[u]变成0,这个差值最大是2^32,则由低位到高位看哪一位是1的就往上跳2^(该位)步
    if(u==v)return u;
    for(int k=31;k>=0;k--)
        if(dsu[k][u]!=dsu[k][v]){		//如果两个结点往上走2^k步仍未相遇
            u=dsu[k][u];			//则都更新为往上走2^k步的结点
            v=dsu[k][v];
        }
    return dsu[0][u];				//u与v是同一个父亲时会停下来,输出其父亲即可
}
int main(){
    cin>>n>>q;
    for(int i=1;i>a>>b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    rt=1;init();
    while(q--){
        cin>>a>>b;
        cout<

 

你可能感兴趣的:(ACM笔记-2串树)