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. c# 图片 与 BASE64 字符串 互相转换。

    using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System. ...

  2. java转义符的一些用法

    那么这里在列上一些转义字符 \\ 反斜杠 \t 间隔 ('\u0009')\n 换行 ('\u000A')\r 回车 ('\u000D')\d 数字 等价于 [0-9]\D 非数字 等价于 [^0-9 ...

  3. HTML文本/文字竖直方向/纵向显示

    HTML vertical text (Safari, Firefox, Chrome, and Opera) .vText { -moz-transform: rotate(-90deg) tran ...

  4. nohup后台运行jar与关闭

    nohup 用途:LINUX命令用法,不挂断地运行命令.  语法:nohup Command [ Arg ... ] [ & ]  描述:nohup 命令运行由 Command 参数和任何相关 ...

  5. UVA 12307 Smallest Enclosing Rectangle(旋转卡壳)

    题意:给你一些点,找出两个可以包含所有点的矩形,一个保证矩形面积最小,一个保证矩形周长最小,输出两个最小值 题解:首先根据所有点求一个凸包,再在这个凸包上枚举每条边,作为矩形的一条边(这样可以保证最小 ...

  6. 查找和删除倒数第n个节点的问题

    class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } public class NthNodeFromEnd ...

  7. codeforces707B:Bakery

    Description Masha wants to open her own bakery and bake muffins in one of the n cities numbered from ...

  8. 爬虫之MongoDB的图片

    聚合:

  9. 机器学习(四)—逻辑回归LR

    逻辑回归常见问题:https://www.cnblogs.com/ModifyRong/p/7739955.html 推导在笔记上,现在摘取部分要点如下: (0) LR回归是在线性回归模型的基础上,使 ...

  10. gym强化学习入门demo——随机选取动作 其实有了这些动作和反馈值以后就可以用来训练DNN网络了

    # -*- coding: utf-8 -*- import gym import time env = gym.make('CartPole-v0') observation = env.reset ...