連結:http://acm.hdu.edu.cn/showproblem.php?pid=2586
題意:一棵有邊權的樹,問任意兩點間的長度是多少。
思路:做LCA題目看到的這道題,就用LCA做了,其實隻用LCA的遞歸部分就能做這道題了。
用一個數組dis記錄根節點到每個節點的距離,則任意兩節點a、b間的距離就是dis[a]+dis[b]-2*dis[lca(a,b)]。
我用vector,交G++要RE,交C++得手動擴棧才能過
LCA離線算法
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 40100
#define eps 1e-7
#define INF 0x7FFFFFFF
#define LLINF 0x7FFFFFFFFFFFFFFF
#define seed 1313131
#define MOD 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct node{
int v,w,next;
}edge[4*MAXN];
int head[MAXN];
int father[MAXN];
int num[MAXN];
int ind[MAXN];//儲存每個節點的入度
int vis[MAXN];
int ancestor[MAXN];
vector<int> Qes[MAXN];
map<pair<int,int>,int>mp;
int query[210][2];
int cnt;
int dis[MAXN];
void add_edge(int u,int v,int w){
edge[cnt].v = v;
edge[cnt].w = w;
edge[cnt].next = head[u];
head[u] = cnt++;
}
void init(int n){
cnt = 0;
mp.clear();
for(int i=1;i<=n;i++){
dis[i] = 0;
head[i] = -1;
num[i] = 1;
father[i] = i;
ind[i] = 0;
ancestor[i] = 0;
Qes[i].clear();
}
}
int Find(int x){
int t = x;
while(t!=father[t])
t = father[t];
int k = x;
while(k!=t){
int temp = father[k];
father[k] = t;
k = temp;
}
return t;
}
int Union(int x,int y){
int a=Find(x);
int b=Find(y);
if(a==b)
return 0;
else if(num[a]<=num[b]){
father[a] = b;
num[b] += num[a];
}
else{
father[b] = a;
num[a] += num[b];
}
return 1;
}
void LCA(int u,int len){
int i,j;
ancestor[u]=u;
dis[u] = len;
for(i=head[u];i!=-1;i=edge[i].next){
int v = edge[i].v;
LCA(v,len+edge[i].w);
Union(u,v);
ancestor[Find(u)] = u;
}
vis[u] = 1;
int _size = Qes[u].size();
for(i=0;i<_size;i++){
if(vis[Qes[u][i]]){
pair<int,int> p;
if(u>Qes[u][i]) p = make_pair(Qes[u][i],u);
else p = make_pair(u,Qes[u][i]);
mp[p] = ancestor[Find(Qes[u][i])];
}
}
}
int main(){
int t,i,j,n,q;
int a,b,c;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&q);
init(n);
for(i=1;i<n;i++){
scanf("%d%d%d",&a,&b,&c);
add_edge(a,b,c);
ind[b]++;
}
for(i=0;i<q;i++){
scanf("%d%d",&a,&b);
Qes[a].push_back(b);
Qes[b].push_back(a);
query[i][0] = min(a,b);
query[i][1] = max(a,b);
}
for(i=1;i<=n;i++){
if(ind[i]==0){
LCA(i,0);
break;
}
}
for(i=0;i<q;i++){
pair<int,int> p = make_pair(query[i][0],query[i][1]);
printf("%d\n",dis[query[i][0]]+dis[query[i][1]]-2*dis[mp[p]]);
}
printf("");
}
return 0;
}