zoukankan      html  css  js  c++  java
  • HDU 2586 How Far Away? LCA水题

    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
    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
     
     
     
     
    题意:给出一棵树,m个询问
    每次询问给出a,b
    问a,b的距离。
     
    siz[i]  表示i到根节点的距离
     
    思路:先求出lca=LCA(a,b)
     
    则距离 = siz[a]+siz[b]-2*siz[lca]
     
     
     
      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 
      5 using namespace std;
      6 
      7 const int maxn=40000+5;
      8 
      9 struct Edge
     10 {
     11     int to,next,w;
     12 }edge[maxn<<1];
     13 int head[maxn];
     14 int tot;
     15 int p[maxn][24];
     16 int siz[maxn];
     17 int dep[maxn];
     18 
     19 void init(int n)
     20 {
     21     tot=1;
     22     memset(head,-1,sizeof(head));
     23     memset(siz,0,sizeof(siz));
     24     memset(dep,0,sizeof(dep));
     25 
     26     for(int i=1;i<=n;i++)
     27         for(int j=0;j<24;j++)
     28             p[i][j]=-1;
     29 }
     30 
     31 void addedge(int u,int v,int w)
     32 {
     33     edge[tot].to=v;
     34     edge[tot].w=w;
     35     edge[tot].next=head[u];
     36     head[u]=tot++;
     37 }
     38 
     39 void dfs(int n,int u,int fa)
     40 {
     41     for(int i=head[u];~i;i=edge[i].next)
     42     {
     43         int v=edge[i].to;
     44         int w=edge[i].w;
     45         if(!dep[v]&&v!=fa)
     46         {
     47             dep[v]=dep[u]+1;
     48             p[v][0]=u;
     49             siz[v]=siz[u]+w;
     50             dfs(n,v,u);
     51         }
     52     }
     53 }
     54 
     55 void init_lca(int n)
     56 {
     57     for(int j=1;(1<<j)<=n;j++)
     58     {
     59         for(int i=1;i<=n;i++)
     60         {
     61             if(p[i][j-1]!=-1)
     62             {
     63                 p[i][j]=p[p[i][j-1]][j-1];
     64             }
     65         }
     66     }
     67 }
     68 
     69 int solve(int n,int u,int v)
     70 {
     71     if(u==v)
     72         return 0;
     73     if(dep[u]<dep[v])
     74     {
     75         swap(u,v);
     76     }
     77 
     78     int init_u=u;
     79     int init_v=v;
     80 
     81     int cnt;
     82     for(cnt=0;(1<<cnt)<=dep[u];cnt++)
     83         ;
     84     cnt--;
     85 
     86     for(int j=cnt;j>=0;j--)
     87     {
     88         if(dep[u]-(1<<j)>=dep[v])
     89             u=p[u][j];
     90     }
     91 
     92     if(u==v)
     93         return (siz[init_u]-siz[u]);
     94 
     95     for(int j=cnt;j>=0;j--)
     96     {
     97         if(p[u][j]!=-1&&p[u][j]!=p[v][j])
     98         {
     99             u=p[u][j];
    100             v=p[v][j];
    101         }
    102     }
    103     int lca=p[u][0];
    104 
    105     return (siz[init_u]+siz[init_v]-2*siz[lca]);
    106 
    107 }
    108 
    109 int main()
    110 {
    111     int test;
    112     scanf("%d",&test);
    113 
    114     while(test--)
    115     {
    116         int n,m;
    117         scanf("%d%d",&n,&m);
    118 
    119         init(n);
    120 
    121         for(int i=1;i<n;i++)
    122         {
    123             int u,v,w;
    124             scanf("%d%d%d",&u,&v,&w);
    125             addedge(u,v,w);
    126             addedge(v,u,w);
    127         }
    128 
    129         dfs(n,1,-1);
    130         init_lca(n);
    131 
    132         /*
    133         for(int i=1;i<=n;i++)
    134             printf("%d
    ",siz[i]);
    135         */
    136 
    137         for(int i=1;i<=m;i++)
    138         {
    139             int u,v;
    140             scanf("%d%d",&u,&v);
    141             //printf("eee
    ");
    142             printf("%d
    ",solve(n,u,v));
    143         }
    144     }
    145 
    146     return 0;
    147 }
    31ms
     
     
     
     
     

     

  • 相关阅读:
    使用Docker及k8s启动logstash服务
    在kubernetes上部署zookeeper,kafka集群
    k8s configmap 挂载配置文件
    k8s 安装 rabbitMQ 单机版
    aws 挂载efs (nfs)目录
    长白山游记
    RedHat 安装YUM软件
    mysql查询案例
    mysql子查询
    mysql联合查询
  • 原文地址:https://www.cnblogs.com/-maybe/p/4499195.html
Copyright © 2011-2022 走看看