HDU--2586(LCA,树上倍增)

2015-02-09 11:20:50

思路:比较裸的树上倍增,用的二分倍增。

  至于距离的计算,只要用dis数组记录下每个节点到根的距离,然后u点和v点之间的距离就是:dis[u] + dis[v] - 2 * dis[lca]

  嘛... 要敲扩栈命令喔~

  1 #pragma comment(linker, "/STACK:1024000000,1024000000")
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <cmath>
  6 #include <vector>
  7 #include <map>
  8 #include <set>
  9 #include <stack>
 10 #include <queue>
 11 #include <string>
 12 #include <iostream>
 13 #include <algorithm>
 14 using namespace std;
 15 
 16 #define MEM(a,b) memset(a,b,sizeof(a))
 17 #define REP(i,n) for(int i=1;i<=(n);++i)
 18 #define REV(i,n) for(int i=(n);i>=1;--i)
 19 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
 20 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i)
 21 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
 22 #define MP(a,b) make_pair(a,b)
 23 
 24 typedef long long ll;
 25 typedef pair<int,int> pii;
 26 const int INF = (1 << 30) - 1;
 27 const int MAXN = 40010;
 28 const int MAX_LOG = 16;
 29 
 30 int T,n,m;
 31 int first[MAXN],ecnt;
 32 int fa[MAX_LOG][MAXN],dep[MAXN];
 33 ll dis[MAXN];
 34 
 35 struct edge{
 36     int v,next,w;
 37 }e[MAXN << 1];
 38 
 39 void Add_edge(int u,int v,int c){
 40     e[++ecnt].next = first[u];
 41     e[ecnt].v = v;
 42     e[ecnt].w = c;
 43     first[u] = ecnt;
 44 }
 45 
 46 void Dfs(int p,int pre,int d){
 47     fa[0][p] = pre;
 48     dep[p] = d;
 49     for(int i = first[p]; ~i; i = e[i].next){
 50         int v = e[i].v;
 51         if(v == pre) continue;
 52         dis[v] = dis[p] + e[i].w;
 53         Dfs(v,p,d + 1);
 54     }
 55 }
 56     
 57 void Pre(){
 58     dis[1] = 0;
 59     Dfs(1,-1,0);
 60     for(int k = 0; k + 1 < MAX_LOG; ++k){
 61         for(int v = 1; v <= n; ++v){
 62             if(fa[k][v] < 0) fa[k + 1][v] = -1;
 63             else fa[k + 1][v] = fa[k][fa[k][v]];
 64         }
 65     }
 66 }
 67 
 68 int Lca(int u,int v){
 69     if(dep[u] > dep[v]) swap(u,v);
 70     for(int k = MAX_LOG - 1; k >= 0; --k){
 71         if((dep[v] - dep[u]) & (1 << k))
 72             v = fa[k][v];
 73     }
 74     if(u == v) return u; //u为v的根
 75     for(int k = MAX_LOG - 1; k >= 0; --k){
 76         if(fa[k][u] != fa[k][v]){
 77             u = fa[k][u];
 78             v = fa[k][v];
 79         }
 80     }
 81     return fa[0][u]; //u离lca只差一步
 82 }
 83 
 84 int main(){
 85     int a,b,c;
 86     scanf("%d",&T);
 87     REP(tt,T){
 88         MEM(first,-1);
 89         ecnt = 0;
 90         scanf("%d%d",&n,&m);
 91         REP(i,n - 1){
 92             scanf("%d%d%d",&a,&b,&c);
 93             Add_edge(a,b,c);
 94             Add_edge(b,a,c);
 95         }
 96         Pre();
 97         REP(i,m){
 98             scanf("%d%d",&a,&b);
 99             int lca = Lca(a,b);
100             printf("%I64d\n",dis[a] + dis[b] - (dis[lca] << 1));
101         }
102     }
103     return 0;
104 }

 

posted @ 2015-02-08 23:23  Naturain  阅读(211)  评论(0编辑  收藏  举报