一看到qtree就以为是lct或者熟练剖分什么的了,后来一看这不是倍增lca的纱布题吗。。。然后。。。粘了个板子,然后。。。。板子错了(orz)。。。。
感谢丁神帮我跳出了板子里的错
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
int deep[20010],depth[20010],fa[20010][32],link[20010],e_tot=0;
struct rec
{
int num,w,next;
}e[30100];
void insert(int x,int y,int z)
{
e_tot++;e[e_tot].num=y;e[e_tot].w=z;e[e_tot].next=link[x];link[x]=e_tot;
}
void dfs(int v,int u,int d,int w)
{
deep[v]=d;
depth[v]=w;
fa[v][0]=u;
for (int p=link[v];p;p=e[p].next)
{
int tmp=e[p].num;
if (tmp==u) continue;
dfs(tmp,v,d+1,w+e[p].w);
}
}
int lca(int x,int y)
{
if (deep[x]<deep[y]) swap(x,y);
int t=deep[x]-deep[y];
for (int i=0;i<=15;i++)
if (t&(1<<i)) x=fa[x][i];
if (x==y) return x;
for (int i=15;i>=0;i--)
if (fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
int main()
{
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
char s[11];
int tmp,tmp2,x,y,z,ans,t,n,k;
scanf("%d",&t);
while (t--)
{
memset(link,0,sizeof(link));
e_tot=0;
scanf("%d",&n);
for (int i=1;i<=n-1;i++)
{
scanf("%d%d%d",&x,&y,&z);
insert(x,y,z);
insert(y,x,z);
}
dfs(1,0,1,0);
for (int i=1;i<=15;i++)
for (int j=1;j<=n;j++)
fa[j][i]=fa[fa[j][i-1]][i-1];
while (scanf("%s",s))
{
if (strcmp(s,"DONE")==0) break;
if (strcmp(s,"DIST")==0)
{
scanf("%d%d",&x,&y);
tmp=lca(x,y);
printf("%d\n",depth[x]+depth[y]-2*depth[tmp]);
}
if (strcmp(s,"KTH")==0)
{
scanf("%d%d%d",&x,&y,&k);
tmp=lca(x,y);
if (deep[x]-deep[tmp]+1>=k)
{
k--;
ans=x;
tmp2=0;
while (k>0)
{
if (k%2==1) x=fa[x][tmp2];
k=k>>1;
tmp2++;
}
printf("%d\n",x);
}
else
{
k=(deep[x]+deep[y]-2*deep[tmp]+1)-k;
ans=y;
tmp2=0;
while (k>0)
{
if (k%2==1) y=fa[y][tmp2];
k=k>>1;
tmp2++;
}
printf("%d\n",y);
}
}
}
}
return 0;
}
误。,。。