http://acm.hdu.edu.cn/showproblem.php?pid=2586
在lca的基础上维护一下距离 维护是在并查集里进行的
代码:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <algorithm> #include <map> #include <vector> #include <set> #include <stack> #include <queue> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int N=100005; const int M=N*2; int head[N],I; struct node { int j,next,d; }edge[M]; struct question { int l,r,lca,dist; }q[N]; bool visited[N]; int f[N],d[N]; vector<int>vt[N],vtd[N]; int fx(int x) { if(f[x]!=x) { int tmp=f[x]; f[x]=fx(f[x]); d[x]+=d[tmp]; } return f[x]; } void add(int i,int j,int d) { edge[I].j=j; edge[I].d=d; edge[I].next=head[i]; head[i]=I++; } void init(int n,int m) { for(int i=0;i<=n;++i) {vt[i].clear();vtd[i].clear();} memset(head,-1,sizeof(head));I=0; for(int i=1;i<n;++i) { int l,r,d; scanf("%d %d %d",&l,&r,&d); add(l,r,d); add(r,l,d); } for(int i=1;i<=m;++i) { scanf("%d %d",&q[i].l,&q[i].r); if(q[i].l==q[i].r) {q[i].lca=q[i].l;q[i].dist=0;continue;} q[i].lca=-1; q[i].dist=-1; vt[q[i].l].push_back(i); vt[q[i].r].push_back(i); } } void findLca(int x) { for(unsigned int i=0;i<vt[x].size();++i) { int w=vt[x][i]; int k; if(q[w].l==x) k=q[w].r; else k=q[w].l; if(visited[k]==true) { q[w].lca=fx(k); vtd[q[w].lca].push_back(w); } } } void findDist(int x) { for(unsigned int i=0;i<vtd[x].size();++i) { int w=vtd[x][i]; fx(q[w].l);fx(q[w].r); q[w].dist=d[q[w].l]+d[q[w].r]; } } void dfs(int x,int pre,int L) { visited[x]=true; f[x]=x; d[x]=0; findLca(x); for(int t=head[x];t!=-1;t=edge[t].next) { int j=edge[t].j; if(visited[j]==false) dfs(j,x,edge[t].d); } findDist(x); f[x]=pre; d[x]=L; } void lca(int n,int m) { for(int i=0;i<=n;++i) f[i]=i; memset(visited,false,sizeof(visited)); dfs(1,1,0); } int main() { //freopen("data.in","r",stdin); int T; scanf("%d",&T); while(T--) { int n,m; scanf("%d %d",&n,&m); init(n,m); lca(n,m); for(int i=1;i<=m;++i) printf("%d\n",q[i].dist); } }