HDU - 2586 How far away ?(暴力 | LCA)

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

题目:

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

题意:给定一棵带权树,m次询问,两个点之间的距离。

题解:暴力DFS。

 1 #include <vector>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5
 6 const int N=12345;
 7 int fa[N],ans;
 8 vector < pair<int,int> > E[N];
 9 vector < pair<int,int> > q[N];
10 bool root[N],vis[N];
11
12 void init(){
13     for(int i=0;i<N;i++){
14         fa[i]=i;
15         E[i].clear();
16         q[i].clear();
17         vis[i]=false;
18         root[i]=true;
19     }
20 }
21
22 int Find(int x){
23     return fa[x]==x?x:fa[x]=Find(fa[x]);
24 }
25
26 void Union(int x,int y){
27     int fx=Find(x),fy=Find(y);
28     if(fx!=fy){
29         fa[fy]=fx;
30     }
31 }
32
33 void solve(int u){
34     vis[u]=1;
35     for(int i=0;i<E[u].size();i++){
36         int v=E[u][i];
37         if(vis[v]) continue;
38         solve(v);
39         Union(u,v);
40     }
41     for(int i=0;i<q[u].size();i++){
42         int v=q[u][i];
43         if(!vis[v]) continue;
44         ans=Find(v);
45     }
46 }
47
48 int main(){
49     int t,n,m;
50     scanf("%d",&t);
51     while(t--){
52         int u,v,w;
53         init();
54         scanf("%d%d",&n,&m);
55         for(int i=1;i<n;i++){
56             scanf("%d%d%d",&u,&v,&w);
57             E[u].push_back(make_pair(v,w));
58             E[v].push_back(make_pair(u,w));
59         }
60         for(int i=1;i<=m;i++){
61             scanf("%d%d",&u,,&v);
62             Q[u].push_back(make_pair(v,i));
63             Q[v].push_back(make_pair(u,i));
64         }
65         tarjan();
66
67     }
68     return 0;
69 }

原文地址:https://www.cnblogs.com/Leonard-/p/8733105.html

时间: 2024-10-28 06:55:05

HDU - 2586 How far away ?(暴力 | LCA)的相关文章

HDU 2586 How far away ? (LCA最近公共祖先)

题目地址:HDU 2586 LCA第一发. 纯模板题. 偷懒用的vector,结果一直爆栈.把G++改成C++就过了.. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <se

【HDU 2586 How far away?】LCA问题 Tarjan算法

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给出一棵n个节点的无根树,每条边有各自的权值.给出m个查询,对于每条查询返回节点u到v的最短路径的权值和,按查询顺序输出结果. 数据范围:n [2, 40000], m[1, 200] 思路:Tarjan算法:dfs遍历每个点,每遍历完 r 的一个孩子 c, 把 c 并入以 r 为祖先的集合,并处理 c 的所有查询 q:若qi的目标节点 v 已被遍历到,那么一定有lca(c, v) =

HDU 2586 How far away ?(LCA裸题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 #include<bits/stdc++.h> #define lson rt << 1, l, m #define rson rt << 1 | 1, m + 1, r using namespace std; typedef long long ll; static const ll inf = (1 << 32); static const int

hdu 2586 How far away? (LCA模板)

题意: N个点,形成一棵树,边有长度. M个询问,每个询问(a,b),询问a和b的距离 思路: 模板题,看代码.DFS预处理算出每个结点离根结点的距离. 注意: qhead[maxn],而不是qhead[maxm]. 输出用%I64d,不要用%lld. C++ RE后 尝试用 G++交. 代码: struct node{ int to,w,next,lca; }; int const maxn = 40005; int const maxm = 205; int fa[maxn]; int he

HDU - 2586 How far away ?(LCA)

题目大意:给出一张连通图,问两个点之间的距离 解题思路:LCA裸题 #include <cstdio> #include <cstring> #define N 40010 #define M 80010 struct Edge{ int to, next, dis; }E[M]; struct Question { int x, y; }Q[N]; int n, m ,tot; int head[N], dist[N], f[N], LCA[N]; bool vis[N]; vo

HDU 2586 How far away ? (LCA,Tarjan, spfa)

题意:给定N个节点一棵树,现在要求询问任意两点之间的简单路径的距离,其实也就是最短路径距离. 析:用LCA问题的Tarjan算法,利用并查集的优越性,产生把所有的点都储存下来,然后把所有的询问也储存下来,然后从树根开始搜索这棵树, 在搜索子树的时候,把并查集的父结点不断更新,在搜索时计算答案,d[i] 表示从根结点到 i 结点的距离,然后分别计算到两个结点的距离, 再减去2倍的根结点到他们公共最近的结点距离,就OK了.不过这个题有个坑人的地方,不用输出那个空行,否则就是PE. 因为这个题询问比较

hdu 2874 Connections between cities hdu 2586 How far away ? LCA

两道lca模板题,用的是倍增法,nlogn预处理,logn查询. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; #define maxn 10100 struct Edge { int u,v,w,next; }e[100100]; int n,m,c; int head[maxn],cnt; int fa[ma

HDU 2586 How far away ? &lt;&lt; LCA转RMQ+ST表 求树上任两点最短距离裸题

此题还有LCA+tarjin离线查询做法,详见这里 关于ST表 解决RMQ问题,dp[i][j]表示从第i位开始长度为(1<<j)的区间的最值 维护的时候采用倍增思想,维护dp[i][j+1]=opt(dp[i][j],dp[i+(1<<j)][j]) 查询的时候,两端点为l,r,则长度len=r-l,寻找一个k,使(1<<k)大于等于len/2,这样就使得 [l,l+(1<<k)]和[r-(1<<k),r]覆盖整个区间 然后此时,就可以直接用s

hdu 2586 How far away ? ( 离线 LCA , tarjan )

How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10312    Accepted Submission(s): 3743 Problem Description There are n houses in the village and some bidirectional roads connecting

LCA(最近公共祖先)--tarjan离线算法 hdu 2586

HDU 2586 How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11320    Accepted Submission(s): 4119 Problem Description There are n houses in the village and some bidirectional roads c