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\n",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 }
时间: 2024-10-22 14:58:12

hdu 2586 (lca-RMQ)的相关文章

hdu 2586 LCA模板题(离线算法)

http://acm.hdu.edu.cn/showproblem.php?pid=2586 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&quo

HDU 2586 LCA转RMQ

点击打开链接 题意:就是问两个节点间的距离 思路:又切了一道模版水题,不解释了,看不懂变量含义的可以看我写的这篇,解释的比较详细ZOJ 3195 #include <vector> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef

HDU 2586 LCA模板题

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2586 题目大意:在一个无向树上,求一条链权和. 解题思路: 0 | 1 /   \ 2      3 设dist[i]为i到根0的链和,求法(Dfs过程中dist[v]=dist[u]+e[i].w) 对于树中任意两点形成的链,可以通过LCA最近公共祖先剖分. 比如2->3,就可以经过LCA点1:  2->1->3 链和=dist[u]+dist[v]-2*dist[LCA[u,v]] (

HDU 2586 LCA

LCA模板题. DFS记录好,到根结点的距离. #include <bits/stdc++.h> using namespace std; const int maxn = 40000+5; const int logmaxn = 20; struct Edge { int to,w; }; std::vector<Edge> G[maxn]; int f[maxn],dis[maxn],deep[maxn],p[maxn][20],n; struct LCA { int n; i

HDU 2586 LCA离线算法 tarjan算法

LCA tarjan算法模板题 题意:给一个无根树,有q个询问,每个询问两个点,问两点的距离. 用tarjan离线算法算出每个询问的两点的最近公共祖先 ans[i]=dis[x[i]]+dis[y[i]]-2*dis[z[i]]; //  x[i],y[i]分别存储每次询问的两点,z[i]存储这两点的最近公共祖先 #include "stdio.h" #include "string.h" int tot,n,m; int f[40010],x[40010],y[4

hdu 2586(LCA+并查集)

How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6734    Accepted Submission(s): 2498 Problem Description There are n houses in the village and some bidirectional roads connecting

HDU 2586 How far away ? (LCA最近公共祖先)

题目地址:HDU 2586 LCA第一发. 纯模板题. 偷懒用的vector,结果一直爆栈.把G++改成C++就过了.. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <se

LCA(最近公共祖先)--tarjan离线算法 hdu 2586

HDU 2586 How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11320    Accepted Submission(s): 4119 Problem Description There are n houses in the village and some bidirectional roads c

最近公共祖先(lca) hdu 2586

hdu 2586 How far away ? 题目大意:给定n-1条边构成一棵树,无向的:和m个询问,对于每一个询问按顺序回答. 结题思路:lca算法算出最近公共祖先,然后dis[u]+dis[v]-2*dis[father](father是u,v的最近公共祖先),小trick是在构造询问树的时候把权值设成询问对应的输入顺序 #include <iostream> #include <cstdio> #include <cstring> #include <al

hdu 2586 How far away ?倍增LCA

hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增求取LCA,同时跟新距离数组 因为 \(2^{16} > 40000\) 所以所以表示祖先的数组dp[][]第二维取到16即可 就这道题来说,与比较tarjan比较,稍快一点 代码: #include <iostream> #include <algorithm> #includ