2586 How far away ? (LCA求樹上兩點間距離模板題)
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
題解:
首先要知道:樹上任意兩點A,B之間的距離 = 根節點到A的距離 + 根節點到B的距離 - 2*根節點到AB最近公共祖先節點的距離。
然後只要求LCA就行了。
Tarjan離線版程式碼:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 40005;
pair<int,int> P[205];//存詢問邊
int lca[205];//存詢問邊對應的最近公共祖先
struct Edge{//存樹邊
int to,next,w;//w為邊權
}E[MAXN*2];
int head[MAXN],tot;
inline void Add(int from,int to,int w){
E[++tot].next = head[from];
E[tot].to = to;
E[tot].w = w;
head[from] = tot;
E[++tot].next = head[to];
E[tot].to = from;
E[tot].w = w;
head[to] = tot;
}
struct Query{//存每個點對應的詢問邊
int to,next,id;
}Q[405];
int headQ[MAXN],totq;
inline void AddQ(int from,int to,int id){
Q[++totq].next = headQ[from];
Q[totq].to = to;
Q[totq].id = id;
headQ[from] = totq;
Q[++totq].next = headQ[to];
Q[totq].to = from;
Q[totq].id = id;
headQ[to] = totq;
}
int dis[MAXN];//記錄根節點到每個點的距離
bool vis[MAXN];
int fa[MAXN];//並查集祖先陣列
int Find(int x){
if(fa[x] == x)return x;
return fa[x] = Find(fa[x]);
}
void Union(int a,int b){
int A = Find(a);
int B = Find(b);
if(A != B)fa[B] = A;
}
void Tarjan(int rt){
vis[rt] = true;
int to;
for(int i=head[rt] ; i ; i=E[i].next){
to = E[i].to;
if(!vis[to]){
dis[to] = dis[rt] + E[i].w;
Tarjan(to);
Union(rt,to);
}
}
for(int i=headQ[rt] ; i ; i=Q[i].next){
to = Q[i].to;
if(vis[to]){
lca[Q[i].id] = Find(to);
}
}
}
inline void init(int n){
for(int i=0 ; i<=n ; ++i)fa[i] = i;
memset(vis,false,sizeof vis);
memset(head,0,sizeof head);
memset(headQ,0,sizeof headQ);
tot = totq = 0;
}
int main(){
int T,n,m;
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
init(n);
int a,b,c;
for(int i=1 ; i<n ; ++i){
scanf("%d %d %d",&a,&b,&c);
Add(a,b,c);
}
for(int i=1 ; i<=m ; ++i){
scanf("%d %d",&P[i].first,&P[i].second);
AddQ(P[i].first,P[i].second,i);
}
dis[1] = 0;//這裡選的根節點為 1
Tarjan(1);
for(int i=1 ; i<=m ; ++i){
printf("%d\n",dis[P[i].first]+dis[P[i].second]-2*dis[lca[i]]);
}
}
return 0;
}
相關推薦
2586 How far away ? (LCA求樹上兩點間距離模板題)
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 i
HDU 2586 How far away ?(LCA Tarjan/樹上倍增)
題目:問任意兩個點之間的最短路徑長。 如果用Tarjan做的話,那麼 用LCA算出最近公共祖先lca,長度就是dis[u]+dis[v]-2*dis[lca] #include<iostream> #include<cstdio> #incl
HDU 2586 How far away ?(LCA模板 近期公共祖先啊)
sizeof rmq round pad show mod 部分 cas sam 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n hou
HDU 2586 How far away ?(LCA在線算法實現)
計算 algo size vector tar urn target nbsp struct http://acm.hdu.edu.cn/showproblem.php?pid=2586 題意:給出一棵樹,求出樹上任意兩點之間的距離。 思路: 這道題可以利用LC
hdu 2586 How far away ? 離線LCA
相加 ref 雙向 std pid edge markdown syn down 題目鏈接:hadu 2586 題目大意: 城鎮之間互相有道路(雙向邊),且只存在n-1條邊,保證相互可達,求兩點 之間的距離。 思路: 轉化為LCA裸問題,只需要再一邊尋找最近公共祖先的
hdu 2586 How far away ?倍增LCA
printf truct != algorithm for sin can -i cnblogs hdu 2586 How far away ?倍增LCA 題目鏈接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 針對
HDU - 2586 How far away? 在線LCA ST算法
ole poi cto st算法 求解 style after nsis return There are n houses in the village and some bidirectional roads connecting them. Every day peo
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): 25408 &nbs
HDU 2586 How far away?(LCA使用詳解)
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
hdu 2586 How far away ?
unique time first turn chm rom memset def nsis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S
HDU-2586 How far away?
ota for each length name amp pac simple return 解題思路 How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K
hdu——2586 How far away ?
ostream style ask read sea sim bottom following ems How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K
HDU - 2586 How far away ?
cti blog ever simple nes printf const you print There are n houses in the village and some bidirectional roads connecting them. Every day
F. Drivers Dissatisfaction+最小生成樹+lca求樹上兩點的最大值
continue tmp rst spa 題解 去掉 題意 drive .com 題目鏈接:F. Drivers Dissatisfaction 題意:n個點,m條邊,每條邊有一個w,代表這條路的不滿意度,每一條邊我們可以花費c來使不滿意讀-1;然後問你有s,找到一棵生成
2586. How far away ?(HDU)
題意理解 一個村莊有很多戶人家,任意兩戶人家最多有一條路相連。已知每條路相連的兩戶人家的編號和長度,求從A戶人家到B戶人家有多遠? 問題分析 LCA+RMQ資料結構,最近公共祖先+區間最小值 轉1:首先用圖表示村莊的連線情況。使用鄰接表儲存,使用heads陣列存節點資訊,使用edge
POJ 4718 /// 樹鏈剖分+線段樹區間合併 求樹上兩點間的LCIS長度
題目大意: 給定n個點 每個點都有權值 接下來給定樹的n條邊 第 i 個數 a[i] 表示 i+1到a[i]之間 有一條邊 給定q q個詢問 每次詢問給出 x y 求x到y的最長上升子序列的長度 題解 https://blog.csdn.net/forever_wjs/article/
POJ 4718 /// 樹鏈剖分+線段樹區間合並 求樹上兩點間的LCIS長度
一次 tree 部分 i+1 clu 給定 top namespace oid 題目大意: 給定n個點 每個點都有權值 接下來給定樹的n條邊 第 i 個數 a[i] 表示 i+1到a[i]之間 有一條邊 給定q q個詢問 每次詢問給出 x y 求x到y的最長上升子序列的長度
求任意多邊形面積(模板題)
題目描述 眾所周知的是,小X特別喜歡由線條組成的形狀,比如說凸多邊形,這一天小X正在紙上畫著喜歡的凸多邊形,這時候小Y走了過來,指著一張圖片上的多邊形,問小X知道這個圖形的面積麼,這可把小X難住了,聰明的你一定能夠幫助小X解決這個問題,對吧~ 輸入描述: 多邊形上最多有
How far away ? HDU - 2586(LCA Tarjan離線方法 or 倍增線上方法)
How far away ? HDU - 2586 題目連結 題意:給出一棵樹,問任意兩點的間的最小距離; 思路:考慮本題,若t時a, b的LCA,r是樹根那麼dis[a, b]=dis[r, a]+dis[r, b]-2*dis[r, t]; dis[r, p] (根到p點
HDU How far away ?--LCA
while nts 分享 put numbers ont integer simple people Problem Description There are n houses in the village and some bidirectional roads co