题目链接:传送门

题意:

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

分析:

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模板题,倍增)

    题干: There are n houses in the village and some bidirectional roads connecting them. Every day peole ...

  2. POJ 1330 Nearest Common Ancestors 【LCA模板题】

    任意门:http://poj.org/problem?id=1330 Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000 ...

  3. HDU - 4547 CD操作(LCA模板)

    题目链接:点击查看 题目大意:给出一个层层嵌套的树状结构,可以从某一点通过一个操作直接到达任意一个子节点的位置,但如果要从某个节点到达其祖先节点需要一层一层往上爬,问若要从节点A到达节点B,需要多少步 ...

  4. LCA模板(数剖实现)

    题目链接:https://www.luogu.org/problemnew/show/P3379 题意:LCA模板题. 思路:今天开始学树剖,先拿lca练练.树剖解lca,两次dfs复杂度均为O(n) ...

  5. hdu 2586 How far away? (LCA模板)

    题意: N个点,形成一棵树,边有长度. M个询问,每个询问(a,b),询问a和b的距离 思路: 模板题,看代码.DFS预处理算出每个结点离根结点的距离. 注意: qhead[maxn],而不是qhea ...

  6. 图论-有向图的连通性模板题(hdu1296)(hdu1827)

    1.强连通分量: 强连通分量可以理解为边数最少的情况下是一个环. 这里写了一个模板题用的是tarjan算法,当然还有其他算法. tarjan算法的关键其实还是对于num数组和low数组的使用 然后可以 ...

  7. P1339 热浪 最短路径模板题

    这么naive的题面一看就是最短路模板题~~~ ok.首先是floyd算法,tts,记得把k放在最外面就行了. 1 #include <cstdio> 2 #include <cst ...

  8. HDU2255 奔小康赚大钱(km模板题)

    Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子.         这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓, ...

  9. HDU1166 敌兵布阵(树状数组模板题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  10. 数单词 (AC自动机模板题)

    数单词 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 为了能够顺利通过英语四六级考试,现在大家每天早上都会早起读英语. LYH本来以为自己在6月份的考试中可以通过六级, ...

最新文章

  1. 【转】TCP、UDP数据包大小的限制
  2. SpringIOC配置文件「bean」标签的属性id class name scope init-method destroy-method factory-bean factory-method
  3. AngelToken揭秘区块链之四大链
  4. Orion Network Performance Monitor 软件在网络管理中的应用
  5. Java程序员必备:常见OOM异常分析
  6. NEERC 2012
  7. 灵格斯怎么屏幕取词_完整页灵格斯词霸怎么用,灵格斯词霸使用教程_9号资讯
  8. UCenter 通信
  9. 3D游戏开发中的矩阵详解
  10. 微信公众号插入百度地址导航功能
  11. 30行python代码实现微信自动陪女盆友聊天(itchat-uos + 无限制调用)
  12. 美国芯片陆续转向,或许为当初的做法后悔不迭,芯片补贴也难改局面
  13. 新AlphaGo首度揭秘:单机运行,4个TPU,算法更强
  14. 中華電信國際漫遊服務一覽表
  15. CSDN使用MD编辑器修改插入的图片管理
  16. oracle日志保存时间设置,关于日志设置的详细介绍
  17. HBase介绍、搭建、环境、安装部署
  18. 关于成都 Gopher Meetup 的回顾
  19. 蛙泳的动作教学口诀(转自新浪博客)
  20. MySQL条件查询简单汇总

热门文章

  1. Win10扬声器未插入怎么解决?
  2. result_of 用法
  3. Stream.of()用法示例
  4. 中国抗生素产业运行状况与需求前景规模预测报告2022版
  5. 用纯css打造表格第一行和前几列锁定
  6. xp系统服务器找不到打印机无法连接失败,xp系统打印机共享提示连接失败的解决方法...
  7. labview编程小技巧
  8. Java美颜相机(1)图像处理
  9. IPv6与IPv4的区别 网信办等三部推进IPv6规模部署
  10. 转载一篇心灵鸡汤,致在路上奋斗的ACMer