zoukankan      html  css  js  c++  java
  • HDU 2586 How far away ?(LCA在线算法实现)

    http://acm.hdu.edu.cn/showproblem.php?pid=2586

    题意:
    给出一棵树,求出树上任意两点之间的距离。

    思路:

    这道题可以利用LCA来做,记录好每个点距离根结点的距离,然后只要计算出两点的LCA,这样一来答案就是distance[u]+distance[v]-2distance[LCA]。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<sstream>
      6 #include<vector>
      7 #include<stack>
      8 #include<queue>
      9 #include<cmath>
     10 #include<map>
     11 #include<set>
     12 using namespace std;
     13 typedef long long ll;
     14 typedef pair<int,ll> pll;
     15 const int INF = 0x3f3f3f3f;
     16 const int maxn=40000+5;
     17 
     18 int n, m;
     19 int num;
     20 int tot;
     21 int head[maxn];
     22 int vis[maxn];
     23 int ver[2*maxn];
     24 int deep[2*maxn];
     25 int dir[maxn];
     26 int first[maxn];
     27 int dp[2*maxn][25];
     28 
     29 struct node
     30 {
     31     int v,w;
     32     int next;
     33 }e[2*maxn];
     34 
     35 void addEdge(int u, int v, int w)
     36 {
     37     e[num].v=v;
     38     e[num].w=w;
     39     e[num].next=head[u];
     40     head[u]=num++;
     41 }
     42 
     43 void dfs(int u, int dep)
     44 {
     45     vis[u]=1;
     46     ver[++tot]=u;   //遍历序列
     47     first[u]=tot;   //结点第一次出现位置
     48     deep[tot]=dep;     //深度
     49     for(int i=head[u];i!=-1;i=e[i].next)
     50     {
     51         if(!vis[e[i].v])
     52         {
     53             int v=e[i].v, w=e[i].w;
     54             dir[v]=dir[u]+w;   //距离
     55             dfs(v,dep+1);
     56             ver[++tot]=u;      //回溯
     57             deep[tot]=dep;
     58         }
     59     }
     60 }
     61 
     62 void ST(int n)
     63 {
     64     for(int i=1;i<=n;i++)  dp[i][0]=i;
     65     for(int j=1;(1<<j)<=n;j++)
     66         for(int i=1;i+(1<<j)-1<=n;i++)
     67         {
     68             int a=dp[i][j-1],b=dp[i+(1<<(j-1))][j-1];
     69             dp[i][j]=deep[a]<deep[b]?a:b;
     70         }
     71 }
     72 
     73 int RMQ(int L, int R)
     74 {
     75     int k=0;
     76     while((1<<(k+1))<=R-L+1)  k++;
     77     int a=dp[L][k], b=dp[R-(1<<k)+1][k];
     78     return deep[a]<deep[b]?a:b;
     79 }
     80 
     81 int LCA(int u, int v)
     82 {
     83     int x=first[u], y=first[v];   //查找出他最先出现的地方
     84     if(x>y)  swap(x,y);
     85     int res=RMQ(x,y);    //查询出的是他祖先的下标
     86     return ver[res];
     87 }
     88 
     89 int main()
     90 {
     91     //freopen("in.txt","r",stdin);
     92     int T;
     93     scanf("%d",&T);
     94     while(T--)
     95     {
     96         num=0; tot=0;
     97         memset(head,-1,sizeof(head));
     98         memset(vis,0,sizeof(vis));
     99         scanf("%d%d",&n,&m);
    100         for(int i=1;i<n;i++)
    101         {
    102             int u,v,w;
    103             scanf("%d%d%d",&u,&v,&w);
    104             addEdge(u,v,w);
    105             addEdge(v,u,w);
    106         }
    107         dir[1]=0;
    108         dfs(1,1);
    109         ST(2*n-1);
    110         while(m--)
    111         {
    112             int u,v;
    113             scanf("%d%d",&u,&v);
    114             int lca=LCA(u,v);
    115             printf("%d
    ",dir[u]+dir[v]-2*dir[lca]);
    116         }
    117     }
    118     return 0;
    119 }
  • 相关阅读:
    ASP.NET 2.0的页面缓存功能介绍
    第五课 主定理
    HDU 1051 Wooden Sticks
    一行代码让浏览器变编辑器
    算法概论习题1001Forest
    第七课 寻找强连通分量
    8223. Tiling a Grid With Dominoes
    迷宫
    第八课 最小生成树之Kruskal
    解决 Ubuntu 12.04 无法调节屏幕亮度的问题
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7294987.html
Copyright © 2011-2022 走看看