求树节点的深+换根
给一个有n个节点的树,节点编号为1~n,默认1为根,支持如下操作
1.查询某个节点的深度
2.设置一个节点为新的根
输出操作1的值,根节点深度为1
1.查询某个节点的深度
2.设置一个节点为新的根
输出操作1的值,根节点深度为1
#include<bits/stdc++.h> using namespace std; const int maxn=16+10; struct node{ int to; int nxt; }E[maxn<<1]; int h[maxn],f[maxn][25],dep[maxn],lg[maxn],etot; void addedge(int x,int y) { E[++etot].to=y; E[etot].nxt=h[x]; h[x]=etot; } void dfs(int u,int fa) { dep[u]=dep[fa]+1; f[u][0]=fa; for (int i=1;(1<<i)<=dep[u];i++) { f[u][i]=f[f[u][i-1]][i-1]; } for (int i=h[u];i;i=E[i].nxt) { int v; v=E[i].to; if (v!=fa) { dfs(v,u); } } } int lca(int x,int y) { if (dep[x]<dep[y]) swap(x,y); int d=dep[x]-dep[y]; while(d) { int k=lg[d]; x=f[x][k]; d-=(1<<k); } if (x==y) return x; for (int i=lg[dep[x]];i>=0;i--) { if (f[x][i]!=f[y][i]) { x=f[x][i]; y=f[y][i]; } } return f[x][0]; } int main() { int n,m,rk=1; cin>>n>>m; for (int i=1;i<n;i++) { int x,y; cin>>x>>y; addedge(x,y); addedge(y,x); } for (int i=2;i<=n;i++) lg[i]=lg[i>>1]+1; dfs(rk,0); for (int i=1;i<=m;i++) { int opt,u; cin>>opt; if (opt==1) { cin>>u; int lc=lca(rk,u); cout<<dep[rk]+dep[u]-2*dep[lc]+1<<endl; } else if(opt==2) { cin>>rk; } } } /* in 5 6 1 2 1 3 3 4 4 5 1 5 2 4 1 1 1 5 1 3 1 2 out 4 3 2 2 4 in 6 7 1 2 1 3 3 4 4 5 3 6 1 5 2 4 1 1 1 5 1 3 1 2 1 6 out 4 3 2 2 4 3 in 7 8 1 2 1 3 3 4 4 5 3 6 5 7 1 5 2 4 1 1 1 5 1 3 1 2 1 6 1 7 out 4 3 2 2 4 3 3 */