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

题意:n个村庄构成一棵无根树,q次询问,求任意两个村庄之间的最短距离

思路:求出两个村庄的LCA,dis[ i ] 表示结点 i 到树根的距离,那么任意两点u,v的最短距离就是dis[ u ]  - dis [LCA] + dis [ v ] - dis[ LCA ]。代码是用tarjan做的,算是模板,记录一下。

AC代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int maxn = ;
struct node{//询问的结点x,y
int x,y;
int lca;
}query[maxn];
struct e{//建边
int to;
int val;
};
int dis[maxn];
vector<e> G[maxn];
vector<int> Q[maxn];
bool vis[maxn];
int N;
int fa[maxn];
void init(){//初始化父亲结点
for(int i = ;i<maxn;i++) fa[i] = i;
}
int find(int x){//并查集find函数
if(x == fa[x]) return x;
return fa[x] = find(fa[x]);
}
void tarjan(int cur){
vis[cur] = true;//标记cur已访问过
for(auto q:Q[cur]){//遍历包含cur结点的询问
if(query[q].x == cur){
if(vis[query[q].y]) {//若x == cur且y已经被访问过,搜y的祖先,就是其LCA
query[q].lca = find(query[q].y);
}
}
else{
if(vis[query[q].x]){//若y == cur且x已经被访问过,搜x的祖先,就是其LCA
query[q].lca = find(query[q].x);
}
}
}
for(auto e:G[cur]){//遍历cur结点的儿子结点
int v = e.to , len = e.val ;
if(vis[v]) continue;
dis[v] = dis[cur] + len;//dis记录cur到root的距离
tarjan(v);
fa[v] = cur; //设置cur结点子节点的父亲为cur
}
}
int main(){
int t;scanf("%d",&t);
while(t--){
scanf("%d",&N);
int q;
memset(vis,,sizeof(vis));
init();
for(int i = ;i<maxn;i++) {//初始化
Q[i].clear() ,G[i].clear() ;
query[i].lca = ,query[i].x = ,query[i].y = ;
}
scanf("%d",&q);
for(int i = ;i<=N-;i++){
int u,v,k;
scanf("%d%d%d",&u,&v,&k);
G[u].push_back({v,k}); //建图
G[v].push_back({u,k});
}
for(int i = ;i<=q;i++){
scanf("%d%d",&query[i].x ,&query[i].y );
Q[query[i].x ].push_back(i);
Q[query[i].y ].push_back(i); //离线存储所有询问 ,i为标号
}
tarjan();
for(int i = ;i<=q;i++){
int LCA = query[i].lca ;
int ans = dis[query[i].x ] + dis[query[i].y ] - *dis[LCA];//输出所有的询问
printf("%d\n",ans);
}
}
return ;
}

HDU 2586 ( LCA/tarjan算法模板)的更多相关文章

  1. hdu 2586 lca在线算法(朴素算法)

    #include<stdio.h> #include<string.h>//用c/c++会爆栈,用g++ac #define inf 0x3fffffff #define N ...

  2. hdu 2586(Tarjan 离线算法)

    How far away ?                                                                             Time Limi ...

  3. 最近公共祖先LCA(Tarjan算法)的思考和算法实现

    LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...

  4. 最近公共祖先LCA(Tarjan算法)的思考和算法实现——转载自Vendetta Blogs

    LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...

  5. [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]

    参考: 1. 郭华阳 - 算法合集之<RMQ与LCA问题>. 讲得很清楚! 2. http://www.cnblogs.com/lazycal/archive/2012/08/11/263 ...

  6. Tarjan 算法求 LCA / Tarjan 算法求强连通分量

    [时光蒸汽喵带你做专题]最近公共祖先 LCA (Lowest Common Ancestors)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili tarjan LCA - YouTube Tarj ...

  7. Tarjan 算法&模板

    Tarjan 算法 一.算法简介 Tarjan 算法一种由Robert Tarjan提出的求解有向图强连通分量的算法,它能做到线性时间的复杂度. 我们定义: 如果两个顶点可以相互通达,则称两个顶点强连 ...

  8. HDU 2586 LCA

    题目大意: 多点形成一棵树,树上边有权值,给出一堆询问,求出每个询问中两个点的距离 这里求两个点的距离可以直接理解为求出两个点到根节点的权值之和,再减去2倍的最近公共祖先到根节点的距离 这是自己第一道 ...

  9. POJ 1330 Nearest Common Ancestors(LCA Tarjan算法)

    题目链接:http://poj.org/problem?id=1330 题意:给定一个n个节点的有根树,以及树中的两个节点u,v,求u,v的最近公共祖先. 数据范围:n [2, 10000] 思路:从 ...

随机推荐

  1. CF 150E Freezing with Style [长链剖分,线段树]

    \(sol:\) 给一种大常数 \(n \log^2 n\) 的做法 考虑二分,由于是中位数,我们就二分这个中位数,\(x>=mid\)则设为 \(1\),否则为 \(-1\) 所以我们只需要找 ...

  2. python ide 使用

    pycharm jupyter 官方文档 使用 部署到服务器 参考 配置域名(反向代理) *.conf文件 server { listen ; server_name ju.iii.top; inde ...

  3. Java(四)输出和输入函数

    介绍一下Java里简单常用的输入输出方法. Java的输出函数很简单,直接调用System类的out对象的print函数即可. 代码: System.out.print(a);//输出变量a的值 Sy ...

  4. beego控制器介绍

    控制器介绍 提示:在 v1.6 中,此文档所涉及的 API 有重大变更,this.ServeJson() 更改为 this.ServeJSON(),this.TplNames 更改为 this.Tpl ...

  5. bugkuCTF-管理员系统(IP伪造)

    题目地址:http://123.206.31.85:1003/ 登进去是一个管理员后台登录的样子 试了sql的万能密码,发现进不了,而且下面还报错了ip禁止 禁止了我们的ip,但是他本地的ip肯定没有 ...

  6. IO流学习之字符流(三)

    IO流之字符流缓冲区: 概念: 流中的缓冲区:是先把程序需要操作的数据保存在内存中,然后我们的程序读写数据的时候,不直接和持久设备之间交互,而改成和内存中的数据进行交互. 缓冲区:它就是临时存储数据, ...

  7. PTA 1001 A+B Format

    问题描述: Calculate a+b and output the sum in standard format -- that is, the digits must be separated i ...

  8. pandas 将多个dataframe保存为一个excel文件的多个sheet表中

    # 创建文件 def create(): df1 = pd.DataFrame({"a1": [1, 2, 3], "b1": [4, 5, 6]}) df2 ...

  9. sqli-labs less-15 --> less-16

    Less-15(布尔/时间盲注) 1.判断是否存在注入点 无论是输入admin/admin’/admin” 都显示回显正常,于是执行uname=admin' and sleep(5)#&pas ...

  10. codeforces 99999/553 Sultan's Pearls Solution 珍珠 题解

    文章目录 珍珠 题意 分析 增加限定条件 去掉限定条件 Code 珍珠 题意 一共n课珍珠,m颗悬挂,其余在桌子上.如图所示. 仆人每天从某一端"借"一颗珍珠珠.主人每天都会检查悬 ...