How far away?

来源:互联网 发布:snh48知乎娱乐圈地位 编辑:程序博客网 时间:2024/05/01 08:45

链接:

  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


题意:

  给你t个测试样例,每个测试样例开头给你一组n m,n个点,m条询问,然后是n-1条边u v w,u和v之间的路径长度为w,最后是m条询问,问你u v之间的距离。


思路:

  dfs一遍求出每个点到树根的距离,然后求出u和v的lca,两个点的距离就是cost[u] + cost[v] - 2 * cost[lca(u,v)]


实现:

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <queue>void read(int &x){ x=0;char c=getchar();while(c<'0' || c>'9')c=getchar();while(c>='0' && c<='9'){ x=x*10+c-'0';c=getchar(); }}void write(int x){ int y=10,len=1;while(y<=x)   {y*=10;len++;}while(len--){y/=10;putchar(x/y+48);x%=y;}}using namespace std;const int maxn = 40007;int n, m, up[maxn][37], dep[maxn], _, cost[maxn];bool vis[maxn];vector<pair<int, int> > edge[maxn];void addedge(int u, int v, int w) {    edge[u].emplace_back(v,w);    edge[v].emplace_back(u,w);}void dfs(int u, int d) {    dep[u] = d; vis[u] = true;    for(auto i : edge[u]) {        int v = i.first;        if (!vis[v]) {            cost[v] = cost[u] + i.second;            dfs(v, d + 1);            up[v][0] = u;        }    }}void process() {    for(int j=1 ; j<31 ; j++)        for(int i=1 ; i<=n ; i++)            if(up[i][j-1] != -1)/*if(up[i][j] != -1)*/                up[i][j] = up[up[i][j-1]][j-1];}int lca(int u, int v) {    if(dep[u] < dep[v]) swap(u,v);    int tmp = dep[u] - dep[v];    for(int j=0 ; j<31 && dep[u] != dep[v] ; j++) {        if(tmp & (1<<j))            u = up[u][j];    }    if(u == v) return v;    for(int j = 30 ; j>=0 ; j--) {        if(up[u][j] != up[v][j])            u = up[u][j], v = up[v][j];    }    return up[u][0];}int main() {#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);#endif    read(_);    while(_--!=0) {        read(n),read(m);        memset(dep, -1, sizeof dep);        memset(up, -1, sizeof up);        memset(vis, 0, sizeof vis);        memset(cost, 0, sizeof cost);        for(int i=1, u, v, w ; i<n ; i++) {            read(u),read(v),read(w);            addedge(u,v,w);        }        dfs(1,1);        process();        for(int i=0, u, v ; i<m ; i++) {            read(u),read(v);            int tmp = lca(u,v);            write(cost[u]+cost[v]-cost[tmp]-cost[tmp]);            cout << '\n';        }        for(int i=0 ; i<=n ; i++) edge[i].clear();    }    return 0;}
原创粉丝点击