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

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"? 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.
 
Input
First line is a single integer T(T<=10), indicating
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.
 
Output
For each test case,output m lines. Each line represents
the answer of the query. Output a bland line after each test case.
 
Sample Input
2
3 2
1 2 10
3 1 15
1 2
2 3

2 2
1 2 100
1 2
2 1

 
Sample Output
10
25
100
100
 
Source
 
Recommend
lcy   |   We have carefully selected several similar
problems for you:  3486 2874 2888 3234 2818 
 

这一道题目意思是说,村庄之间有路可达,给你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和倍增模版的更多相关文章

  1. P3703 [SDOI2017]树点涂色 LCT维护颜色+线段树维护dfs序+倍增LCA

    \(\color{#0066ff}{ 题目描述 }\) Bob有一棵\(n\)个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点 ...

  2. 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...

  3. 洛谷P3379 【模板】最近公共祖先(LCA)(dfs序+倍增)

    P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...

  4. HDU 3078 Network(LCA dfs)

    Network [题目链接]Network [题目类型]LCA dfs &题意: 给出n个点的权值,m条边,2种操作 0 u num,将第u个点的权值改成num k u v,询问u到v这条路上 ...

  5. 【BZOJ】2819: Nim(树链剖分 / lca+dfs序+树状数组)

    题目 传送门:QWQ 分析 先敲了个树链剖分,发现无法AC(其实是自己弱,懒得debug.手写栈) 然后去学了学正解 核心挺好理解的,$ query(a) $是$ a $到根的异或和. 答案就是$ l ...

  6. nowcoder172C 保护 (倍增lca+dfs序+主席树)

    https://www.nowcoder.com/acm/contest/172/C (sbw大佬太强啦 orz) 先把每一个路径(x,y)分成(x,lca),(y,lca)两个路径,然后就能发现,对 ...

  7. 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 ...

  8. 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 ...

  9. luogu3320 寻宝游戏 (dfs序+倍增lca+set)

    一定是从随便某个点开始,然后按着dfs序的顺序跑一圈是最好的 所以说,新加一个点x,就减少了dis(pre,next),增加了dis(pre,x),dis(x,nxt) 删掉一个点同理 这个可以用se ...

随机推荐

  1. SpringMVC实现AJax以及RestFull风格

    RestFull风格就是url路径中不能出现?不能带参数,如https://www.baidu.com/user/item/1234这个格式,也叫url资源定位 1.需要在web.xml中开启put, ...

  2. Luogu-2495 [SDOI2011]消耗战

    虚树第一题 对于每次询问的点建立一棵虚树,然后在树上DP,一个点的答案就是这个点的父边切断的代价与所有儿子切断的代价去最小值,当然如果这个节点是资源点则必须切父边 注意在虚树上一条边的代价应该是中间所 ...

  3. JQuery小知识点

    //get() : 就是把JQ转成原生JS,可以让通过jquery获得元素使用JS的innerHTML方法. $(function(){ //document.getElementById('div1 ...

  4. Struts2学习(2)

    1.结果嗯配置 (1)全局结果页面 (2)局部结果页面 (3)result标签type属性 2.在action获取表单提交数据 (1)使用ActionContext类获取 (2)使用ServletAc ...

  5. SQL Server 中WITH (NOLOCK)浅析(转)

    概念介绍  开发人员喜欢在SQL脚本中使用WITH(NOLOCK), WITH(NOLOCK)其实是表提示(table_hint)中的一种.它等同于 READUNCOMMITTED . 具体的功能作用 ...

  6. Dom节点操作常用方法

    1.访问/获取节点 document.getElementById(id); //返回对拥有指定id的第一个对象进行访问 document.getElementsByName(name); //返回带 ...

  7. TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute【转】

    转自:http://blog.csdn.net/goodboy1881/article/details/670761 1.IMCP协议介绍 前面讲到了,IP协议并不是一个可靠的协议(是一种尽力传送的协 ...

  8. AliRedis单机180w QPS, 8台服务器构建1000w QPS Cache集群(转)

    http://blog.sina.com.cn/s/blog_e59371cc0101br74.html 引言:        如今redis凭借其高性能的优势, 以及丰富的数据结构作为cache已越 ...

  9. Asp.net 异步调用WebService

    //服务代码 [WebMethod] public string Test(int sleepTimes, int val) { Thread.Sleep(sleepTimes); var log = ...

  10. Python学习之路day3-字符编码与转码

    一.基础概念 字符与字节 字符是相对于人类而言的可识别的符号标识,是一种人类语言,如中文.英文.拉丁文甚至甲骨文.梵语等等.    字节是计算机内部识别可用的符号标识(0和1组成的二进制串,机器语言) ...