求树节点的深+换根

给一个有n个节点的树,节点编号为1~n,默认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
*/ 

  

posted @ 2022-11-05 19:36  心悟&&星际  阅读(25)  评论(0编辑  收藏  举报