zoukankan      html  css  js  c++  java
  • How far away ? LCA求树上两点距离

    How far away ?

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 22976    Accepted Submission(s): 9078


    Problem Description
    There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B"? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path("simple" means you can't visit a place twice) between every two houses. Yout task is to answer all these curious people.
     
    Input
    First line is a single integer T(T<=10), indicating the number of test cases.
      For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n.
      Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.
     
    Output
    For each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.
     
    Sample Input
    2 3 2 1 2 10 3 1 15 1 2 2 3 2 2 1 2 100 1 2 2 1
     
    Sample Output
    10 25 100 100
     
    Source
     
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <queue>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <set>
      7 #include <iostream>
      8 #include <map>
      9 #include <stack>
     10 #include <string>
     11 #include <vector>
     12 #define  pi acos(-1.0)
     13 #define  eps 1e-6
     14 #define  fi first
     15 #define  se second
     16 #define  lson l,m,rt<<1
     17 #define  rson m+1,r,rt<<1|1
     18 #define  bug         printf("******
    ")
     19 #define  mem(a,b)    memset(a,b,sizeof(a))
     20 #define  fuck(x)     cout<<"["<<x<<"]"<<endl
     21 #define  f(a)        a*a
     22 #define  sf(n)       scanf("%d", &n)
     23 #define  sff(a,b)    scanf("%d %d", &a, &b)
     24 #define  sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
     25 #define  sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d)
     26 #define  pf          printf
     27 #define  FRE(i,a,b)  for(i = a; i <= b; i++)
     28 #define  FREE(i,a,b) for(i = a; i >= b; i--)
     29 #define  FRL(i,a,b)  for(i = a; i < b; i++)
     30 #define  FRLL(i,a,b) for(i = a; i > b; i--)
     31 #define  FIN         freopen("DATA.txt","r",stdin)
     32 #define  gcd(a,b)    __gcd(a,b)
     33 #define  lowbit(x)   x&-x
     34 #pragma  comment (linker,"/STACK:102400000,102400000")
     35 using namespace std;
     36 typedef long long LL;
     37 typedef unsigned long long ULL;
     38 const int maxn = 1e5 + 10;
     39 int _pow[maxn], dep[maxn], dis[maxn], vis[maxn], ver[maxn];
     40 int tot, head[maxn], dp[maxn * 2][25], k, first[maxn];
     41 struct node {
     42     int u, v, w, nxt;
     43 } edge[maxn << 2];
     44 void init() {
     45     tot = 0;
     46     mem(head, -1);
     47 }
     48 void add(int u, int v, int w) {
     49     edge[tot].v = v, edge[tot].u = u;
     50     edge[tot].w = w, edge[tot].nxt = head[u];
     51     head[u] = tot++;
     52 }
     53 void dfs(int u, int DEP) {
     54     vis[u] = 1;
     55     ver[++k] = u;
     56     first[u] = k;
     57     dep[k] = DEP;
     58     for (int i = head[u]; ~i; i = edge[i].nxt) {
     59         if (vis[edge[i].v]) continue;
     60         int v = edge[i].v, w = edge[i].w;
     61         dis[v] = dis[u] + w;
     62         dfs(v, DEP + 1);
     63         ver[++k] = u;
     64         dep[k] = DEP;
     65     }
     66 }
     67 void ST(int len) {
     68     int K = (int)(log((double)len) / log(2.0));
     69     for (int i = 1 ; i <= len ; i++) dp[i][0] = i;
     70     for (int j = 1 ; j <= K ; j++) {
     71         for (int i = 1 ; i + _pow[j] - 1 <= len ; i++) {
     72             int a = dp[i][j - 1], b = dp[i + _pow[j - 1]][j - 1];
     73             if (dep[a] < dep[b]) dp[i][j] = a;
     74             else dp[i][j] = b;
     75         }
     76     }
     77 }
     78 int RMQ(int x, int y) {
     79     int K = (int)(log((double)(y - x + 1)) / log(2.0));
     80     int a = dp[x][K], b = dp[y - _pow[K] + 1][K];
     81     if (dep[a] < dep[b]) return a;
     82     else return b;
     83 }
     84 int LCA(int u, int v) {
     85     int x = first[u], y = first[v];
     86     if (x > y) swap(x, y);
     87     int ret = RMQ(x, y);
     88     return ver[ret];
     89 }
     90 int main() {
     91     for (int i = 0 ; i < 40 ; i++) _pow[i] = (1 << i);
     92     int t;
     93     sf(t);
     94     while(t--) {
     95         int n, q;
     96         init();
     97         sff(n, q);
     98         mem(vis, 0);
     99         for (int i = 1 ; i < n ; i++) {
    100             int u, v, w;
    101             sfff(u, v, w);
    102             add(u, v, w);
    103             add(v, u, w);
    104         }
    105         k = 0, dis[1] = 0;
    106         dfs(1, 1);
    107         ST(2 * n - 1);
    108         while(q--) {
    109             int u, v;
    110             sff(u, v);
    111             int lca = LCA(u, v);
    112             printf("%d
    ", dis[u] + dis[v] - 2 * dis[lca]);
    113         }
    114     }
    115     return  0;
    116 }
  • 相关阅读:
    UDP与TCP报文格式,字段意义
    TCP报文头部解析
    SQL中IN和EXISTS用法的区别
    SQL中EXISTS的用法
    rabbitmq之一概念解释(信道、交换器和路由键、队列)
    Memcache,Redis,MongoDB三种非关系型数据库的对比
    linux chage
    linux用户组管理
    c++ decltype
    c++ 隐式转换(explicit与转换构造函数)
  • 原文地址:https://www.cnblogs.com/qldabiaoge/p/9447036.html
Copyright © 2011-2022 走看看