hdu 2586 How far away ?
http://acm.hdu.edu.cn/showproblem.php?pid=2586
也是一道很裸的LCA,只不过卡了一下栈,要自己开大点栈才能过(c++)。
思路:选1为根节点,先得到从根节点出发到每个点的距离,这样任意两个点的距离为:dis(u)+dis(v)-2*dis(lca(u,v)).

#include<stdio.h> #include<string.h> #include<iostream> #include<stdlib.h> #include<vector> #include<algorithm> #pragma comment(linker, "/STACK:36777216")//开大点栈 using namespace std; const int maxn = 40005; struct node { int v,w,next; }edge[maxn*2]; struct nd { int idx,dis; }as[203]; int vis[maxn],ans[maxn]; int head[maxn],f[maxn]; int dis[maxn],ecnt,cnt; vector<int>qes[maxn]; vector<int>rank[maxn]; bool cmp(nd a,nd b){ return a.idx < b.idx; } void add(int u,int v,int w) { edge[ecnt].v = v; edge[ecnt].w = w; edge[ecnt].next = head[u]; head[u] = ecnt++; } int Find(int x) { int i = x,tmp; while(x!=f[x]) x = f[x]; while(i!=f[x]){ tmp = f[i]; f[i] = x; i = tmp;} return f[x]; } void LCA(int pre,int u,int sum) { int i,v,x,y; ans[u] = u; dis[u] = sum; for(i = head[u]; i != -1; i = edge[i].next){ v = edge[i].v; if(v==pre)continue; LCA(u,v,sum+edge[i].w); x = Find(u); y = Find(v); if(x!=y) f[y] = x; ans[Find(u)] = u; } vis[u] = 1; for(i = 0; i < qes[u].size(); ++ i){ v = qes[u][i]; if(vis[v]){ as[cnt].idx = rank[u][i]; as[cnt].dis = dis[v] + dis[u] - dis[ans[Find(v)]] * 2; cnt++; } } } int main() { int i,j,k,u,v,w,n,m,t; scanf("%d",&t); while(t--) { scanf("%d %d",&n,&m); memset(vis,0,sizeof(vis)); memset(ans,0,sizeof(ans)); memset(head,-1,sizeof(head)); for(i = 0; i <= n; ++ i) qes[i].clear(); for(i = 0; i <= n; ++ i) f[i] = i; ecnt = cnt = 0; for(i = 1; i < n; ++ i) { scanf("%d %d %d",&u,&v,&w); add(u,v,w); add(v,u,w); } for(i = 0; i < m; ++ i) { scanf("%d %d",&u,&v); qes[u].push_back(v); qes[v].push_back(u); rank[u].push_back(i); rank[v].push_back(i); } LCA(0,1,0); sort(as,as+cnt,cmp); for(i = 0; i < m; ++ i) printf("%d\n",as[i].dis); }return 0; }