-->

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 }

 

posted @ 2017-02-10 09:35  yangyaojia  阅读(312)  评论(0编辑  收藏  举报