hdu 2586 (lca-RMQ)

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <queue>
  5 #include <cstdio>
  6 #include <algorithm>
  7 #include <map>
  8 #define LL long long
  9 
 10 using namespace std;
 11 const int N = 5e4;
 12 
 13 int head[N],tot;
 14 int sum,dir[N],ver[N*2],R[N*2],first[N],visit[N];
 15 int dp[2*N][25];
 16 struct nodes
 17 {
 18     int to,next,w;
 19 }Edge[N];
 20 
 21 void E_init()
 22 {
 23     tot = 0;
 24     memset(head,-1,sizeof(head));
 25 }
 26 
 27 void add(int u,int v,int w)
 28 {
 29     Edge[tot].to = v;
 30     Edge[tot].w = w;
 31     Edge[tot].next = head[u];
 32     head[u] = tot++;
 33 }
 34 
 35 void dfs(int u,int dep)
 36 {
 37     visit[u] = 1;
 38     ver[++sum] = u;
 39     first[u] = sum;
 40     R[sum] = dep;
 41     for(int i = head[u]; i != -1; i = Edge[i].next)
 42     {
 43         if(!visit[Edge[i].to])
 44         {
 45             dir[Edge[i].to] = dir[u]+Edge[i].w;
 46             dfs(Edge[i].to,dep+1);
 47             ver[++sum] = u;
 48             R[sum] = dep;
 49         }
 50     }
 51 }
 52 
 53 void ST(int n)
 54 {
 55     for(int i = 1; i <= n; i++)
 56         dp[i][0] = i;
 57     for(int j = 1; (1<<j)<=n; j++)
 58     {
 59         for(int i = 1;i+(1<<j)-1<=n; i++)
 60         {
 61             int l,r;
 62             l = dp[i][j-1];
 63             r = dp[i+ (1<<(j-1))][j-1];
 64             dp[i][j] = R[l]<R[r]?l:r;
 65         }
 66     }
 67 }
 68 
 69 int RMQ(int l,int r)
 70 {
 71    //int k = log(r-l+1)/log(2);
 72    int k = 0;
 73    while( (1<<(k+1)) <= r - l + 1) k++;
 74    int ll = dp[l][k], rr = dp[r-(1<<k)+1][k];
 75    return R[ll]<R[rr]?ll:rr;
 76 }
 77 
 78 int LCA(int u,int v)
 79 {
 80     int x = first[u],y = first[v];
 81     if(x > y) swap(x,y);
 82     return ver[RMQ(x,y)];
 83 }
 84 
 85 void solve()
 86 {
 87     int n,q;
 88     scanf("%d %d",&n,&q);
 89     E_init();
 90     for(int i = 0; i < n-1; i++)
 91     {
 92         int u,v,w;
 93         scanf("%d %d %d",&u,&v,&w);
 94         add(u,v,w);
 95         add(v,u,w);
 96     }
 97     memset(visit,0,sizeof(visit));
 98     sum = 0;
 99     dir[1] = 0;
100 
101     dfs(1,1);
102     ST(n*2-1);
103 
104     while(q--)
105     {
106         int a,b,c;
107         scanf("%d %d",&a,&b);
108         c = LCA(a,b);
109         printf("%d
",dir[a]+dir[b]-2*dir[c]);
110     }
111 
112 }
113 
114 int main(void)
115 {
116     int t;
117     scanf("%d",&t);
118     while(t--)
119     {
120         solve();
121     }
122     return 0;
123 }
原文地址:https://www.cnblogs.com/henserlinda/p/5723038.html