HDU 2586 How far away ?, Hdu2586
How far away?Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission (s): 6309 Accepted Submission (s): 2368
Problem DescriptionThere 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.
InputFirst 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.
OutputFor each test case, output m lines. Each line represents the answer of the query. Output a bland line after each test case.
Sample Input
23 21 2 103 1 151 22 32 21 2 1001 22 1
Sample Output
1025100100
The meaning of the question is to give some houses numbers and the distance between the houses with these numbers, and then ask m times to give the numbers of the two houses each time, the minimum distance between the two houses is required. This is a tree chart, that is, a total of N points N-1 side, and then all points can be connected. It is easy to know that this question is the problem of finding the least common ancestor. First, determine a root node, and then calculate the distance from the root node to all nodes by DFS traversal, then we can use the offline tarjan algorithm to find the nearest common ancestor c of two query nodes a and B, the requested result is dist [a]-dist [c] + dist [B]-dist [c]. The meaning is very understandable. Just draw a tree and you can see it, this idea is also easy to think. Here we use a non-recursive DFS to directly find the distance between the highlights. Each time we ask, we use DFS to find the distance between the highlights. It can also be very easy to AC.
#include <cstdio>#include <vector>#include <stack>#include <string>using namespace std;const int N = 40005;int n, m, t;vector<int> adj[N];vector<int> wei[N];int dist[N];bool visit[N];void init(int n){for (int i = 0; i <= n; ++i){adj[i].clear();wei[i].clear();}}int dfs(int x, int y){int res = 0;memset(visit, 0, sizeof(visit));memset(dist, 0, sizeof(dist));stack<int> st;st.push(x);visit[x] = true;while (!st.empty()){int tx = st.top();st.pop();if (tx == y)break;for (int i = 0; i < adj[tx].size(); ++i){int ty = adj[tx][i];if (visit[ty])continue;st.push(ty);visit[ty] = true;dist[ty] = dist[tx] + wei[tx][i];}}return dist[y];}int main(){int a, b, w;scanf("%d", &t);while (t--){scanf("%d %d", &n, &m);init(n);for (int i = 0; i < n - 1; ++i){scanf("%d %d %d", &a, &b, &w);adj[a].push_back(b);adj[b].push_back(a);wei[a].push_back(w);wei[b].push_back(w);}for (int i = 0; i < m; ++i){scanf("%d %d", &a, &b);printf("%d\n", dfs(a, b));}if (t != 0)printf("\n");}return 0;}