How far away ?
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 32860 Accepted Submission(s): 13291
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.
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
Source
Recommend
lcy
Solution
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> q;
const int maxn = 4e4 + 10;
bool vis[maxn], root[maxn];
int ecnt, qcnt, ehead[maxn], qhead[maxn], pre[maxn], lca[maxn], dis[maxn];
struct edge { int to, dis, next; } edges[maxn << 1];
struct que { int id, to, next; } ques[maxn << 1];
vector<q> vec;
inline const int read()
{
int x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
return x * f;
}
int Find(int id) { return pre[id] == id ? id : pre[id] = Find(pre[id]); }
void Union(int a, int b) { pre[Find(b)] = Find(a); }
void addEdge(int u, int v, int w)
{
edges[ecnt].to = v;
edges[ecnt].dis = w;
edges[ecnt].next = ehead[u];
ehead[u] = ecnt++;
}
void addQue(int id, int u, int v)
{
ques[qcnt].id = id;
ques[qcnt].to = v;
ques[qcnt].next = qhead[u];
qhead[u] = qcnt++;
}
void tarjan(int u)
{
vis[u] = true;
for (int i = ehead[u]; ~i; i = edges[i].next)
{
int v = edges[i].to, w = edges[i].dis;
if (!vis[v])
{
dis[v] = dis[u] + w;
tarjan(v);
Union(u, v);
}
}
for (int i = qhead[u]; ~i; i = ques[i].next)
{
int v = ques[i].to, id = ques[i].id;
if (vis[v]) lca[id] = Find(v);
}
}
int main()
{
int t = read();
while (t--)
{
vec.clear();
ecnt = ecnt = 0;
memset(vis, false, sizeof(vis));
memset(ehead, -1, sizeof(ehead));
memset(qhead, -1, sizeof(qhead));
int n = read(), m = read();
for (int i = 1; i <= n; i++)
{
pre[i] = i;
root[i] = true;
}
for (int i = 0; i < n - 1; i++)
{
int u = read(), v = read(), w = read();
root[v] = false;
addEdge(u, v, w);
addEdge(v, u, w);
}
for (int i = 0; i < m; i++)
{
int u = read(), v = read();
addQue(i, u, v);
addQue(i, v, u);
vec.push_back(q(u, v));
}
for (int i = 1; i <= n; i++)
{
if (root[i])
{
dis[i] = 0;
tarjan(i);
}
}
for (int i = 0; i < (int)vec.size(); i++)
{
int u = vec[i].first, v = vec[i].second;
printf("%d\n", dis[u] + dis[v] - dis[lca[i]] * 2);
}
}
return 0;
}