题目:http://acm.hdu.edu.cn/showproblem.php?pid=2586
题意:求树上两点间距离
#include
#include
#include
#include
#include
using namespace std;
const int N = 100100;
struct edge
{
int to, cost, next;
}g[N*2];
int dp[20][N*2];
//dp[i][j]记录的是以j为起点、2的i次方长度内的深度最小点的编号,因为访问2n-1次,数组长度要乘2
int n, m;
int cnt, tot, head[N];
bool vis[N];
int dep[N*2], ver[N*2], fir[N], dis[N];
//ver为访问的节点依次编号,dep记录编号对应的节点的深度,因为访问2n-1次,所有这两个数组长度乘2
void add_edge(int v, int u, int cost)
{
g[cnt].to = u, g[cnt].cost = cost, g[cnt].next = head[v], head[v] = cnt++;
}
void dfs(int v, int cur)
{
vis[v] = true, ver[++tot] = v, dep[tot] = cur, fir[v] = tot;
for(int i = head[v]; i != -1; i = g[i].next)
{
int u = g[i].to;
if(! vis[u])
{
dis[u] = dis[v] + g[i].cost;
dfs(u, cur + 1);
ver[++tot] = v, dep[tot] = cur;
}
}
}
void ST(int n)
{
for(int i = 1; i <= n; i++)
dp[0][i] = i;
for(int i = 1; (1< u) swap(v, u);
int res = rmq(v, u);
return ver[res];
}
int main()
{
int t, a, b, c;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &n, &m);
cnt = 0;
memset(head, -1, sizeof head);
for(int i = 0; i < n - 1; i++)
{
scanf("%d%d%d", &a, &b, &c);
add_edge(a, b, c);
add_edge(b, a, c);
}
memset(vis, 0, sizeof vis);
dis[1] = 0;
tot = 0;
dfs(1, 1);
ST(2 * n - 1);
for(int i = 0; i < m; i++)
{
scanf("%d%d", &a, &b);
int res = lca(a, b);
printf("%d\n", dis[a] + dis[b] - 2 * dis[res]);
}
}
return 0;
}