QTree
1 #include <cstdio> 2 #include <iostream> 3 #include <cmath> 4 #include <queue> 5 #include <algorithm> 6 #include <cstring> 7 #include <climits> 8 #define MAXN 20000+10 9 using namespace std; 10 int n,m,q,num,head[MAXN],t; 11 int v[MAXN],fa[MAXN][100],g[MAXN][100]; 12 int deep[MAXN]; 13 struct Edge{ 14 int next,dis,to,from; 15 }edge[MAXN<<1]; 16 void add(int from,int to,int dis) 17 { 18 edge[++num].next=head[from]; 19 edge[num].to=to; 20 edge[num].from=from; 21 edge[num].dis=dis; 22 head[from]=num; 23 } 24 void dfs(int x) 25 { 26 for(int i=head[x];i;i=edge[i].next) 27 if(!deep[edge[i].to]) 28 { 29 deep[edge[i].to]=deep[x]+1; 30 g[edge[i].to][0]=edge[i].dis; 31 fa[edge[i].to][0]=x; 32 dfs(edge[i].to); 33 } 34 } 35 void init() 36 { 37 deep[1]=1; 38 dfs(1); 39 for(int j=1;(1<<j)<=n;j++) 40 for(int i=1;i<=n;i++) 41 if(fa[i][j-1]) 42 fa[i][j]=fa[fa[i][j-1]][j-1], 43 g[i][j]=g[i][j-1]+g[fa[i][j-1]][j-1]; 44 } 45 int query(int k,int from,int to) 46 { 47 int a=from,b=to; 48 if(deep[a]>deep[b]) swap(a,b); 49 int d=deep[b]-deep[a],ans=0,lca=0; 50 for(int i=0;(1<<i)<=d;i++) 51 if((1<<i)&d) ans+=g[b][i],b=fa[b][i]; 52 if(a==b) lca=a; 53 else 54 { 55 for(int j=30;j>=0;j--) 56 if(fa[a][j]!=fa[b][j]) 57 { 58 ans+=g[a][j]+g[b][j]; 59 a=fa[a][j];b=fa[b][j]; 60 } 61 ans+=g[a][0]+g[b][0];lca=fa[a][0]; 62 } 63 64 if(k==-1) return ans; 65 int df=deep[from]-deep[lca]+1,dt=deep[to]-deep[lca]+1,p=0; 66 if(k==df) return lca; 67 if(k<df) 68 { 69 p=from,k=k-1; 70 } 71 else 72 { 73 p=to,k=(df+dt-1)-k; 74 } 75 for(int j=0;(1<<j)<=k;j++) 76 if((1<<j)&k) p=fa[p][j]; 77 return p; 78 } 79 int main() 80 { 81 freopen("i.in","r",stdin); 82 freopen("i.out","w",stdout); 83 scanf("%d",&t); 84 for(int l=1;l<=t;l++) 85 { 86 num=0; 87 memset(edge,0,sizeof(edge)); 88 memset(head,0,sizeof(head)); 89 memset(fa,0,sizeof(fa)); 90 memset(g,0,sizeof(g)); 91 memset(deep,0,sizeof(deep)); 92 scanf("%d",&n); 93 int x,y,z; 94 for(int i=1;i<n;i++) 95 { 96 scanf("%d%d%d",&x,&y,&z); 97 add(x,y,z); 98 add(y,x,z); 99 } 100 init(); 101 char c[10]; 102 while(scanf("%s",c)&&(!(c[0]=='D'&&c[1]=='O'))) 103 { 104 if(c[0]=='D') 105 { 106 scanf("%d%d",&x,&y); 107 printf("%d\n",query(-1,x,y)); 108 }else 109 if(c[0]=='K') 110 { 111 scanf("%d%d%d",&x,&y,&z); 112 printf("%d\n",query(z,x,y)); 113 } 114 } 115 printf("\n"); 116 } 117 return 0; 118 }