您的位置:首页 > 其它

hdu 2586 How far away ?(LCA)

2015-08-05 18:13 274 查看
/********************************************
**题意是给你一颗树,求树上任意两节点 u ,v 的距离
**所求 u,v 的距离可以用最近公共祖先求得
**设 x 为 u,v 的最近公共祖先,dis[i]为第 i 个结点到树根的距离
**则所求为 dis[u]+dis[v]-2*dis[x];
********************************************/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <vector>
#define N 40010
using namespace std;

vector<int>to
, w
, query
, id
;
int father
, dis
;
int ans[205];
bool vis
;

void init(int n, int m){
for (int i = 0; i <= n; i++){
father[i] = 0;
vis[i] = false;
dis[i] = 0;
to[i].clear();
w[i].clear();
query[i].clear();
id[i].clear();
}
}

void add(int u, int v, int c){
to[u].push_back(v);
w[u].push_back(c);
}

int find_set(int x){
if (x == father[x])return father[x];
return father[x] = find_set(father[x]);
}

void union_set(int x, int y){
x = find_set(x);
y = find_set(y);
father[y] = x;
}

void dfs(int u, int d){

father[u] = u;
vis[u] = true;
dis[u] = d;

for (int i = 0; i < to[u].size(); i++){
int v = to[u][i];
if (vis[v] == false){
dfs(v, d + w[u][i]);
union_set(u, v);
}
}

for (int i = 0; i < query[u].size(); i++){
int v = query[u][i];
if (vis[v] == true){
ans[id[u][i]] = dis[v] + dis[u] - 2 * dis[find_set(v)];
}
}

}

int main(){
int t, n, m;
cin >> t;
while (t--){
cin >> n >> m;
init(n, m);
int u, v, c;
for (int i = 1; i < n; i++){
cin >> u >> v >> c;
add(u, v, c);
add(v, u, c);
}

for (int i = 1; i <= m; i++){
cin >> u >> v;
query[u].push_back(v);
query[v].push_back(u);
id[u].push_back(i);
id[v].push_back(i);
}

dfs(1, 0);

for (int i = 1; i <= m; i++){
cout << ans[i] << endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: