hdu 2586 How far away ?
题目大意:给定n-1条边构成一棵树,无向的;和m个询问,对于每一个询问按顺序回答。
结题思路:lca算法算出最近公共祖先,然后dis[u]+dis[v]-2*dis[father](father是u,v的最近公共祖先),小trick是在构造询问树的时候把权值设成询问对应的输入顺序
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <stack> #include <vector> using namespace std; const int maxn=40000+10; struct node { int v,w,next; }e[maxn<<1],q[maxn<<1]; int ehead[maxn],qhead[maxn],vis[maxn],fa[maxn],dis[maxn],ans[maxn]; int eT,qT; int n,m; void build(node *ed,int *head,int &T,int u,int v,int w) { ed[T].v=v; ed[T].w=w; ed[T].next=head[u]; head[u]=T++; } void init() { memset(ans,0,sizeof(ans)); memset(dis,0,sizeof(dis)); memset(ehead,-1,sizeof(ehead)); memset(qhead,-1,sizeof(qhead)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) fa[i]=i; eT=qT=0; int u,v,w; for(int i=0;i<n-1;i++) { scanf("%d%d%d",&u,&v,&w); build(e,ehead,eT,u,v,w); build(e,ehead,eT,v,u,w); } for(int i=0;i<m;i++) { scanf("%d%d",&u,&v); build(q,qhead,qT,u,v,i); build(q,qhead,qT,v,u,i); } } int getf(int x) { while(x!=fa[x]) { fa[x]=getf(fa[x]); x=fa[x]; } return x; } void dfs(int u) { vis[u]=1; for(int i=ehead[u];~i;i=e[i].next) { int v=e[i].v; if(!vis[v]) { dis[v]=dis[u]+e[i].w; dfs(v); fa[v]=u; } } for(int i=qhead[u];~i;i=q[i].next) { int v=q[i].v; if(vis[v]) { ans[q[i].w]=dis[u]+dis[v]-2*dis[getf(v)]; } } } int main() { int kase; //freopen("in.txt","r",stdin); scanf("%d",&kase); while(kase--) { scanf("%d%d",&n,&m); init(); dfs(1); for(int i=0;i<m;i++) printf("%d ",ans[i]); } return 0; }