zoukankan      html  css  js  c++  java
  • [hdu2586]How far away?(LCA)

    题意:问树上两点之间的最短距离

    解题关键:LCA模板题,在线做法,LCA->RMQ,用st表求解

    这里是用first,rmq数组长度可以减半。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<iostream>
     7 typedef long long ll;
     8 using namespace std;  
     9 const int maxn=40010; 
    10 const int maxm=25;  
    11 int _pow[maxm],m,n;  
    12 int head[maxn],tot;  
    13 int ver[maxn*2],depth[maxn*2],first[maxn],dis[maxn],rmq[maxn*2][maxm],id;//5个数组,注意哪个需要乘2 
    14 
    15 inline int read(){
    16     char k=0;char ls;ls=getchar();for(;ls<'0'||ls>'9';k=ls,ls=getchar());
    17     int x=0;for(;ls>='0'&&ls<='9';ls=getchar())x=(x<<3)+(x<<1)+ls-'0';
    18     if(k=='-')x=0-x;return x;
    19 }
    20 
    21 struct edge{
    22     int to,w,nxt;  
    23 }e[maxn*2];//链式前向星建树 
    24 
    25 void init(){
    26     memset(head,-1,sizeof head);  
    27     tot=0;
    28     id=0;
    29 }
    30 
    31 void add_edge(int u,int v,int w){  
    32     e[tot].to=v;
    33     e[tot].w=w;
    34     e[tot].nxt=head[u];
    35     head[u]=tot++;
    36 }
    37   
    38 void dfs(int u,int fa,int dep){
    39     ver[++id]=u;//第i个访问到的结点编号 
    40     depth[id]=dep;//第i个访问到的结点深度  
    41     first[u]=id;
    42     for(int i=head[u];i!=-1;i=e[i].nxt){
    43         int v=e[i].to;
    44         int w=e[i].w;
    45         if(v==fa) continue;
    46         dis[v]=dis[u]+w;//dis是先序遍历求 
    47         dfs(v,u,dep+1);
    48         ver[++id]=u;//后序遍历,再次访问父节点 
    49         depth[id]=dep;
    50     }
    51 } 
    52   
    53 void rmq_init(int n){  
    54     int k=int(log(n)/log(2));  
    55     for(int i=1;i<=n;i++)    rmq[i][0]=i;  
    56     for(int j=1;j<=k;j++){  
    57         for(int i=1;i+_pow[j]-1<=n;i++){//因为存的是索引 
    58             int a=rmq[i][j-1],b=rmq[i+_pow[j-1]][j-1];  
    59             if(depth[a]<depth[b])    rmq[i][j]=a;  
    60             else  rmq[i][j]=b;  
    61         }
    62     }
    63 }
    64   
    65 int rmq_query(int l,int r){
    66     int k=int(log(r-l+1)/log(2));  
    67     int a=rmq[l][k],b=rmq[r-_pow[k]+1][k];  
    68     if(depth[a]<depth[b])  return a;  
    69     else  return b;
    70 }//返回的依然是索引 
    71   
    72 int LCA(int u,int v){
    73     int x=first[u],y=first[v];  
    74     if(x>y)swap(x,y);  
    75     int res=rmq_query(x,y);  
    76     return ver[res]; 
    77 }
    78 
    79 int main(){
    80     for(int i=0;i<maxm;i++)    _pow[i]=1<<i; //预处理2^n 
    81     int t,a,b,c;
    82     t=read();
    83     while(t--){
    84         init();
    85         n=read();m=read();
    86         for(int i=0;i<n-1;i++) a=read(),b=read(),c=read(),add_edge(a,b,c),add_edge(b,a,c);
    87         dfs(1,-1,0);
    88         rmq_init(2*n-1);
    89         for(int i=0;i<m;i++){
    90             a=read(),b=read();
    91             int ans=LCA(a,b);
    92             printf("%d
    ",dis[a]+dis[b]-2*dis[ans]);
    93         }
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    反素数(暴力)
    More Divisors(反素数)
    CodeForces
    Binary Tree(二叉树+思维)
    Friendship of Frog(水题)
    内网jenkins如何配置gitlab自动拉取代码打包
    配置git使用ssh方式克隆gitlab的代码
    centOS7创建python虚拟环境
    CentOS7下安装JDK
    centOS安装python3 以及解决 导入ssl包出错的问题
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7469487.html
Copyright © 2011-2022 走看看