hdu2586(LCA模板)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2586

还是要多练习,不够熟练。。

可以一看:http://blog.csdn.net/nameofcsdn/article/details/52230548

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<algorithm>
  5 using namespace std;
  6
  7 const int  maxn=40010;
  8
  9 int first[maxn<<1],node[maxn<<1],dep[maxn<<1],dp[maxn<<1][25];
 10 int dis[maxn];
 11 int head[maxn];
 12 int vis[maxn];
 13 int tot,cnt;
 14
 15 struct edge
 16 {
 17     int v,w,nex;
 18 }e[maxn<<1];
 19
 20 void add(int u,int v,int w)
 21 {
 22     e[cnt].v=v;
 23     e[cnt].w=w;
 24     e[cnt].nex=head[u];
 25     head[u]=cnt++;
 26 }
 27 int n,m;
 28 int u,v,w;
 29 void init()
 30 {
 31     for(int i=0;i<=n;i++)
 32     {
 33         head[i]=-1;
 34         vis[i]=0;
 35     }
 36     cnt=tot=0;
 37 }
 38 void dfs(int u,int d,int w)
 39 {
 40     tot++;
 41     vis[u]=1;
 42     first[u]=tot;
 43     node[tot]=u;
 44     dep[tot]=d;
 45     for(int i=head[u];i!=-1;i=e[i].nex) if(!vis[e[i].v])
 46     {
 47         dis[e[i].v]=w+e[i].w;
 48         dfs(e[i].v,d+1,dis[e[i].v]);
 49         tot++;
 50         node[tot]=u;
 51         dep[tot]=d;
 52     }
 53
 54 }
 55 void RMQ_INIT(int n)
 56 {
 57     int k=log2(n);
 58     for(int i=1;i<=n;i++)
 59         dp[i][0]=i;
 60     for(int j=1;j<=k;j++)
 61         for(int i=1;i+(1<<j)-1<=n;i++)
 62     {
 63         int a=dp[i][j-1];
 64         int b=dp[i+(1<<j-1)][j-1];
 65         if(dep[a]<dep[b]) dp[i][j]=a;
 66         else dp[i][j]=b;
 67     }
 68 }
 69 int rmq(int x,int y)
 70 {
 71     int k=log2(y-x+1);
 72     int a=dp[x][k];
 73     int b=dp[y-(1<<k)+1][k];
 74     if(dep[a]<dep[b]) return a;
 75     return b;
 76 }
 77
 78 int lca(int a,int b)
 79 {
 80     int x=first[a];
 81     int y=first[b];
 82     int k;
 83     if(x>y) swap(x,y);
 84     k=rmq(x,y);
 85     return node[k];
 86 }
 87 int main()
 88 {
 89     int t;
 90     scanf("%d",&t);
 91     while(t--)
 92     {
 93         scanf("%d%d",&n,&m);
 94         init();
 95         for(int i=1;i<n;i++)
 96         {
 97             scanf("%d%d%d",&u,&v,&w);
 98             add(u,v,w);
 99             add(v,u,w);
100         }
101
102         dfs(1,1,0);  //任意一点当作根即可
103         RMQ_INIT(tot);
104         while(m--)
105         {
106             scanf("%d%d",&u,&v);
107             printf("%d\n",dis[u]+dis[v]-2*dis[lca(u,v)]);
108         }
109     }
110 }
时间: 2024-08-03 14:40:15

hdu2586(LCA模板)的相关文章

HDU 5296 Annoying problem(LCA模板+树的dfs序心得)

Problem Description Coco has a tree, whose nodes are conveniently labeled by 1,2,-,n, which has n-1 edge,each edge has a weight. An existing set S is initially empty. Now there are two kinds of operation: 1 x: If the node x is not in the set S, add n

LCA模板整理

HDU2586 纯LCA模板 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define lowbit(x) x&(-x) #define rep(i,l,r) for(int i=l;i<=r;++i) #define per(i,r,l) for(int i=r;i>=l;--i) #define ls o<<1 #defin

算法复习——LCA模板(POJ1330)

题目: Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:  In the figure, each node is labeled with an integer from {1, 2,...,16}. Node 8 is the root of the tree. Node x is an ancesto

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

LCA模板(数剖实现)

题目链接:https://www.luogu.org/problemnew/show/P3379 题意:LCA模板题. 思路:今天开始学树剖,先拿lca练练.树剖解lca,两次dfs复杂度均为O(n),每次查询为logn,因此总复杂度为:O(2*n+m*logn). 代码: #include<cstdio> #include<cstring> using namespace std; const int maxn=500005; struct node{ int v,next; }

POJ 1330(LCA模板)

链接:http://poj.org/problem?id=1330 题意:q次询问求两个点u,v的LCA 思路:LCA模板题,首先找一下树的根,然后dfs预处理求LCA(u,v) AC代码: 1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstring> 5 #include<set> 6 #include<string> 7 #incl

HDU2586 How far away ?(LCA模板题)

题目链接:传送门 题意: 给定一棵树,求两个点之间的距离. 分析: LCA 的模板题目 ans = dis[u]+dis[v] - 2*dis[lca(u,v)]; 在线算法:具体讲解 传送门 代码如下: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 40010; struc

hdu 2586 How far away? (LCA模板)

题意: N个点,形成一棵树,边有长度. M个询问,每个询问(a,b),询问a和b的距离 思路: 模板题,看代码.DFS预处理算出每个结点离根结点的距离. 注意: qhead[maxn],而不是qhead[maxm]. 输出用%I64d,不要用%lld. C++ RE后 尝试用 G++交. 代码: struct node{ int to,w,next,lca; }; int const maxn = 40005; int const maxm = 205; int fa[maxn]; int he

hihoCoder_#1067_最近公共祖先&#183;二(LCA模板)

#1067 : 最近公共祖先·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上上回说到,小Hi和小Ho用非常拙劣--或者说粗糙的手段山寨出了一个神奇的网站,这个网站可以计算出某两个人的所有共同祖先中辈分最低的一个是谁.远在美国的他们利用了一些奇妙的技术获得了国内许多人的相关信息,并且搭建了一个小小的网站来应付来自四面八方的请求. 但正如我们所能想象到的--这样一个简单的算法并不能支撑住非常大的访问量,所以摆在小Hi和小Ho面前的无非两种选择: 其一是购买更为昂