How far away ?(LCA)dfs和倍增模版
How far away ?
Tarjan
http://www.cnblogs.com/caiyishuai/p/8572859.html
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 20491 Accepted Submission(s):
8010
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"? Usually it hard to
answer. But luckily int this village the answer is always unique, since the
roads are built in the way that there is a unique simple path("simple" means you
can't visit a place twice) between every two houses. Yout task is to answer all
these curious people.
the number of test cases.
For each test case,in the first line there are
two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses
and the number of queries. The following n-1 lines each consisting three numbers
i,j,k, separated bu a single space, meaning that there is a road connecting
house i and house j,with length k(0<k<=40000).The houses are labeled from
1 to n.
Next m lines each has distinct integers i and j, you areato answer
the distance between house i and house j.
the answer of the query. Output a bland line after each test case.
3 2
1 2 10
3 1 15
1 2
2 3
2 2
1 2 100
1 2
2 1
25
100
100
这一道题目意思是说,村庄之间有路可达,给你N个节点,N-1条路,然后M组查询,查询两个节点之间的距离。
N个节点N-1条边,那么就符合树的定义。所以题目给的就是一个树,就是求树上两个节点的距离。
这一道题目可以和LCA联系起来,求两个节点(a和b)的距离。两个节点必然由一个公共点连接起来,这个点就是LCA(最近公共祖先c)
那么求距离就可以转换为a到根节点的距离+b到根节点的距离—c到根节点的距离—c到根节点的距离。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<functional>
#define N 100000+10
using namespace std;
int n,m;
struct node
{
int to,next,cost;
}e[N];
int cnt;
int fa[][N];
int head[N],depth[N],dis[N];
void init()
{
memset(head,-,sizeof head);
memset(depth,,sizeof depth);
memset(dis,,sizeof dis);
cnt=;
}
void addedge(int u,int v,int w)//建图过程,建双向边
{
e[cnt].to=v;
e[cnt].cost=w;
e[cnt].next=head[u];
head[u]=cnt++;
} void DFS(int u,int f)//遍历树
{
fa[][u]=f;
for(int i=head[u];~i;i=e[i].next)//遍历所有相连的边
{
int To=e[i].to;
if(To!=f)//去掉以后MLE,可能是递归求的过程中太多临时变量
{//建树过程建双向边,会出现to=f的情况,去掉以后会陷入无限递归中
dis[To]=dis[u]+e[i].cost;//更新距离
depth[To]=depth[u]+;//更新深度
DFS(To,u);
}
} } void solve()
{
depth[]=;//题目给的是一个树
dis[]=;//无论怎么样的树,都可以把1视为根节点
DFS(,-);
for(int i=;i<;i++)//树上倍增
for(int j=;j<=n;j++)
fa[i][j]=fa[i-][fa[i-][j] ];
} int LCA(int u,int v)//求最近公共祖先
{
if(depth[u]>depth[v])//保证V的深度比较大
swap(u,v);
for(int i=;i<;i++)//倍增到深度相同
if((depth[v]-depth[u])>>i&)//二进制特性,一定能跳到深度相同
v=fa[i][v];
if(u==v)
return u;
for(int i=;i>=;i--)//两者同时倍增
{
if(fa[i][u]!=fa[i][v])
{
u=fa[i][u];
v=fa[i][v];
}
}
return fa[][v];
}
int main()
{
int i,t;
int a,b,c;
while(scanf("%d",&t)!=EOF)
{ while(t--)
{
init();
scanf("%d%d",&n,&m);
for(i=;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c);
addedge(a,b,c);
addedge(b,a,c);
}
solve();
for(i=;i<=m;i++)
{
scanf("%d%d",&a,&b);
int ans=dis[a]+dis[b]-*dis[LCA(a,b)];
printf("%d\n",ans);
}
}
return ;
}
}
How far away ?(LCA)dfs和倍增模版的更多相关文章
- P3703 [SDOI2017]树点涂色 LCT维护颜色+线段树维护dfs序+倍增LCA
\(\color{#0066ff}{ 题目描述 }\) Bob有一棵\(n\)个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点 ...
- 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树
题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...
- 洛谷P3379 【模板】最近公共祖先(LCA)(dfs序+倍增)
P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...
- HDU 3078 Network(LCA dfs)
Network [题目链接]Network [题目类型]LCA dfs &题意: 给出n个点的权值,m条边,2种操作 0 u num,将第u个点的权值改成num k u v,询问u到v这条路上 ...
- 【BZOJ】2819: Nim(树链剖分 / lca+dfs序+树状数组)
题目 传送门:QWQ 分析 先敲了个树链剖分,发现无法AC(其实是自己弱,懒得debug.手写栈) 然后去学了学正解 核心挺好理解的,$ query(a) $是$ a $到根的异或和. 答案就是$ l ...
- nowcoder172C 保护 (倍增lca+dfs序+主席树)
https://www.nowcoder.com/acm/contest/172/C (sbw大佬太强啦 orz) 先把每一个路径(x,y)分成(x,lca),(y,lca)两个路径,然后就能发现,对 ...
- lca 倍增模版
; void dfs(int u,int fa){ d[u]=d[fa]+; p[u][]=fa; ;i<POW;i++) p[u][i]=p[p[u][i-]][i-]; int sz=edg ...
- D - Project Presentation(DFS序+倍增LCA)
You are given a tree that represents a hierarchy in a company, where the parent of node u is their d ...
- luogu3320 寻宝游戏 (dfs序+倍增lca+set)
一定是从随便某个点开始,然后按着dfs序的顺序跑一圈是最好的 所以说,新加一个点x,就减少了dis(pre,next),增加了dis(pre,x),dis(x,nxt) 删掉一个点同理 这个可以用se ...
随机推荐
- jar 冲突解决方案
val urlOfClass = classOf[Nothing].getClassLoader.getResource("org/slf4j/spi/LocationAwareLogger ...
- JavaWeb -- 四个域对比 request,servletContext, Session, pageContext
requsest: 程序产生数据,用完了就没有用了, 用request, 作用范围:一个请求范围. Session: 程序产生数据,用完了 等一下还要使用, 用Session, 作用范围: 一个会话范 ...
- script标签加载js代码的一些知识
1.script加载js代码是并行加载,顺序执行的,并且在加载和执行js时会阻塞浏览器渲染引擎, 2.defer和async属性添加过后,js的下载和执行就不会阻塞浏览器的渲染引擎了 3.defer会 ...
- Flume-NG源码阅读之HDFSEventSink
HDFSEventSink是flume中一个很重要的sink,配置文件中type=hdfs.与此sink相关的类都在org.apache.flume.sink.hdfs包中. HDFSEventSin ...
- js科里化
科里化定义如下: 首先将一批函数转入一个函数(然后这个函数返回一个新的函数),这中形式就叫“做科里化”(currying) Function.prototype.curry = function(){ ...
- Tensorflow搭建神经网络及使用Tensorboard进行可视化
创建神经网络模型 1.构建神经网络结构,并进行模型训练 import tensorflow as tfimport numpy as npimport matplotlib.pyplot as plt ...
- WPF中的事件及冒泡事件和隧道事件(预览事件)的区别
WPF快速指导10:WPF中的事件及冒泡事件和隧道事件(预览事件)的区别 WPF快速指导10:WPF中的事件及冒泡事件和隧道事件(预览事件)的区别 本文摘要: 1:什么是路由事件: 2:中断事件路 ...
- virualbox andirodx86
背景 谷歌提供的andriod sdk模拟器在windows平台上很卡,是因为sdk是针对arm处理器架构的(就是嵌入式),而我们的windows系统是 x86架构 或者是 AMD架构,所以安卓模拟器 ...
- uva 103 经典DAG变形
https://vjudge.net/problem/UVA-103 也是一个经典的DAG模型,因为书上的翻译和原文不照导致WA两发= = 对于同一维度的两个箱子A,B,A可以嵌套在B中的一个充分条件 ...
- Https---SSL协议
ssl协议的起源和历史我就不再多说了,就是那个Netscape 网景公司开发的,它的作用主要是提供了一种安全传输方式,我们知道网上有很多的时候需要我们去输入用户名和密码,那么假设我们自己的电脑防病毒还 ...