题目链接:传送门

题意:

给定一棵树,求两个点之间的距离。

分析:

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; struct nod{
int to,next,w;
}edge[maxn*2]; int head[maxn],ip,tot;
bool vis[maxn];
int R[maxn*2],ver[maxn*2];
int dp[maxn*2][25];
int first[maxn];
int dis[maxn]; void init(){
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
dis[1]=0,ip=0,tot=0;
} void add(int u,int v,int w){
edge[ip].to=v;
edge[ip].w=w;
edge[ip].next=head[u];
head[u]=ip++;
}
/***
ver[i]=x:第i个点是x.
first[i]=x: 点i第一次出现的位置是x
R[i]=x:第i个点的深度为x;
dis[i]=x;点i到根节点的距离为x.
***/
void dfs(int u,int dept){
vis[u]=true,ver[++tot]=u,first[u]=tot,R[tot]=dept;
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(!vis[v]){
dis[v]=dis[u]+edge[i].w;
dfs(v,dept+1);
ver[++tot]=u,R[tot]=dept;
}
}
} void ST(int n){
for(int i=1;i<=n;i++) dp[i][0]=i;
for(int i=1;(1<<i)<=n;i++){
for(int j=1;j+(1<<i)<=n;j++){
int a = dp[j][i-1],b=dp[j+(1<<(i-1))][i-1];
if(R[a]<R[b]) dp[j][i]=a;
else dp[j][i]=b;
}
}
} int RMQ(int l,int r){
int k=0;
while(1<<(k+1)<=r-l+1)
k++;
int x = dp[l][k], y=dp[r-(1<<k)+1][k];
if(R[x]<R[y]) return x;
else return y;
} int LCA(int u,int v){
u=first[u],v=first[v];
if(u>v) swap(u,v);
return ver[RMQ(u,v)];
} int main(){
int t,n,m;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
init();
for(int i=0;i<n-1;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
dfs(1,1);
ST(2*n-1);
for(int i=0;i<m;i++){
int u,v;
scanf("%d%d",&u,&v);
printf("%d\n",dis[u]+dis[v]-2*dis[LCA(u,v)]);
}
}
return 0;
}

离线算法: 详细解说 传送门

代码例如以下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 40010; struct nod{
int u,v,next,w,lca;
}edge[maxn*2],edge1[maxn]; int par[maxn],ancestors[maxn];
int head[maxn],head1[maxn];
int dis[maxn],ip,ip1;
bool vis[maxn]; void init(){
memset(head1,-1,sizeof(head1));
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
for(int i=1;i<maxn;i++) par[i]=i;
dis[1]=0,ip1=0,ip=0;
} int find_par(int x){
if(x!=par[x]) return par[x]=find_par(par[x]);
return par[x];
} void Union(int u,int v){
u=find_par(u);
v=find_par(v);
if(u!=v) par[v]=u;
} void add(int u,int v,int w){
edge[ip].v=v;
edge[ip].w=w;
edge[ip].next=head[u];
head[u]=ip++;
} void add1(int u,int v){
edge1[ip1].u=u;
edge1[ip1].v=v;
edge1[ip1].lca=-1;
edge1[ip1].next=head1[u];
head1[u]=ip1++;
} void tarjan(int u){
vis[u]=1;
ancestors[u]=par[u]=u;
for(int i=head[u];i!=-1;i=edge[i].next){
int v = edge[i].v;
if(!vis[v]){
dis[v]=dis[u]+edge[i].w;
tarjan(v);
Union(u,v);
}
}
for(int i=head1[u];i!=-1;i=edge1[i].next){
int v = edge1[i].v;
if(vis[v]){
edge1[i].lca=edge1[i^1].lca=ancestors[find_par(v)];
}
}
} int main()
{
int t,n,m;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
init();
for(int i=0;i<n-1;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
for(int i=0;i<m;i++){
int u,v;
scanf("%d%d",&u,&v);
add1(u,v);
add1(v,u);
}
tarjan(1);
for(int i=0;i<m;i++){
printf("%d\n",dis[edge1[i*2].u]+dis[edge1[i*2].v]-2*dis[edge1[i*2].lca]);
}
}
return 0;
}

HDU2586 How far away ?(LCA模板题)的更多相关文章

  1. hdu 2586 How far away?(LCA模板题+离线tarjan算法)

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  2. HDU 2586——How far away ?——————【LCA模板题】

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. HDU 2586 (LCA模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2586 题目大意:在一个无向树上,求一条链权和. 解题思路: 0 | 1 /   \ 2      3 ...

  4. HDU - 2586 How far away ?(LCA模板题)

    HDU - 2586 How far away ? Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & ...

  5. POJ 1986 - Distance Queries - [LCA模板题][Tarjan-LCA算法]

    题目链接:http://poj.org/problem?id=1986 Description Farmer John's cows refused to run in his marathon si ...

  6. [hdu 2586]lca模板题(在线+离线两种版本)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 在线版本: 在线方法的思路很简单,就是倍增.一遍dfs得到每个节点的父亲,以及每个点的深度.然后 ...

  7. HDU 2586 How far away ? 离线lca模板题

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  8. ZOJ 3195 Design the city (LCA 模板题)

    Cerror is the mayor of city HangZhou. As you may know, the traffic system of this city is so terribl ...

  9. HDU 2586 How far away ?【LCA模板题】

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给你N个点,M次询问.1~N-1行输入点与点之间的权值,之后M行输入两个点(a,b)之间的最 ...

随机推荐

  1. [置顶] strcpy和memcpy的区别

    strcpy和memcpy都是标准C库函数,它们有下面的特点. strcpy提供了字符串的复制.即strcpy只用于字符串复制,并且它不仅复制字符串内容,还会复制字符串的结束符. 已知strcpy函数 ...

  2. TCP/IP笔记 二.网络层(2)——ICMP,RIP,OSPF,BGP

    1. ICMP ICMP (Internet Control Message Protocol) 作用:提高 IP 数据报交付成功的机会. 1.1 特点 ICMP 允许主机或路由器报告差错情况和提供有 ...

  3. 【玩转cocos2d-x之四十】怎样在Cocos2d-x 3.0中使用opengl shader?

    有小伙伴提出了这个问题.事实上GLProgramCocos2d-x引擎自带了.全然能够直接拿来用. 先上图吧. 使用opengl前后的对照: watermark/2/text/aHR0cDovL2Js ...

  4. C++ overloading contructor

     // overloading class constructors #include <iostream> using namespace std; class Rectangle ...

  5. 【分享】深入浅出WPF全系列教程及源码

    本人10月份提出离职,可是交接非常慢,预计年底才会交接完,趁着交接之际,自学了一下WPF,由于这是微软未来的发展趋势,自WIN7以来包含前不久公布的WIN8,核心还是WPF,在此,将自己的学习成果做一 ...

  6. 真正理解javascript的五道题目.

    题目一: if (!("a" in window)) { var a = 1; } alert(a); 题目二: var a = 1, b = function a(x) { x ...

  7. 【web开发学习笔记】Structs2 Action学习笔记(一个)

    1.org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter准备和运行 2. <filter-mapping&g ...

  8. [Java学习笔记]Java Tips

    1.Java没有sizeof关键字 , volatile是java关键字.详情见:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166. ...

  9. jquery怎么在点击li标签之后添加一个在class,点击下一个li时删除上一个class?

    思路:点击当前li元素后是用removeClass()删除所有兄弟元素(使用siblings()获取)的class样式,然后使用addClass()为当前li添加class. 具体演示如下: 1.HT ...

  10. 使用svnkit 的相关实例及相关问题汇总

    SVNKIT操作SVN版本库的完整例子 http://www.cnblogs.com/wangjiyuan/p/svnkitwanchenglizi.html#!comments 2.SVNClien ...