How far away ?
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17189 Accepted Submission(s): 6618
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
Tarjan:倍增:#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N = 50005; const LL mod=1e9+7; const int inf = 0x3f3f3f3f; struct edg { int v,w; edg(int a,int b) { v=a; w=b; } }; struct node { int x,i; node(int a,int b) { x=a; i=b; } } ; vector<edg>v[N]; vector<node>query[N]; int fa[N],dis[N],ans[N],LCA[N]; bool vis[N]; int n; void Init() { for(int i=1;i<=n;i++) { v[i].clear(); query[i].clear(); fa[i]=i; dis[i]=0; LCA[i]=-1; vis[i]=false; } return ; } int Find(int x) { if(fa[x]==x) return x; return fa[x]=Find(fa[x]); } void Union(int x,int y) { x=Find(x); y=Find(y); fa[y]=x; return ; } void Tarjan(int s,int f) { dis[s]=f; vis[s]=true; int l=v[s].size(); for(int i=0;i<l;i++) { int x=v[s][i].v; int w=v[s][i].w; if(vis[x])continue; Tarjan(x,f+w); Union(s,x); } l=query[s].size(); for(int i=0;i<l;i++) { int x=query[s][i].x; int y=query[s][i].i; if(!vis[x])continue; LCA[y]=Find(x); ans[y]=dis[x]+dis[s]-2*dis[Find(x)]; } return ; } int main() { int t; scanf("%d",&t); while(t--) { int q,x,y,z; scanf("%d%d",&n,&q); Init(); for(int i=1;i<n;i++) { scanf("%d%d%d",&x,&y,&z); v[x].push_back(edg(y,z)); v[y].push_back(edg(x,z)); } for(int i=0;i<q;i++) { scanf("%d%d",&x,&y); query[x].push_back(node(y,i)); query[y].push_back(node(x,i)); } Tarjan(1,0);//最近公共祖先在LCA数组里 for(int i=0;i<q;i++) printf("%d\n",ans[i]); } return 0; }
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N = 50005; const int inf = 0x3f3f3f3f; struct edg { int v,w,next; }E[N*2]; int cnt,n; int head[N]; int deep[N]; int in[N]; int dis[N]; int fa[N][31]; void add(int u,int v,int w) { E[cnt].v=v;E[cnt].w=w;E[cnt].next=head[u];head[u]=cnt++; E[cnt].v=u;E[cnt].w=w;E[cnt].next=head[v];head[v]=cnt++; } void dfs(int u,int f,int dep,int dist) { deep[u]=dep; dis[u]=dist; fa[u][0]=f; for(int i=head[u];i!=-1;i=E[i].next) { int v=E[i].v; int w=E[i].w; if(!deep[v]) dfs(v,u,dep+1,dist+w); } return ; } void Init() { for(int j=1;(1<<j)<=n;j++) for(int i=1;i<=n;i++) fa[i][j]=fa[fa[i][j-1]][j-1]; } int LCA(int u,int v) { if(deep[u]<deep[v]) u=u^v,v=u^v,u=u^v; int d=deep[u]-deep[v]; for(int i=0;(1<<i)<=d;i++) if((1<<i)&d) u=fa[u][i]; if(u==v) return u; for(int i=20;i>=0;i--) if(fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i]; return fa[u][0]; } int main() { int t; scanf("%d",&t); while(t--) { int q,x,y,z; scanf("%d%d",&n,&q); cnt=0; memset(head,-1,sizeof(head)); for(int i=1;i<n;i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); } memset(deep,0,sizeof(deep)); dfs(1,-1,1,0); Init(); while(q--) { scanf("%d%d",&x,&y); printf("%d\n",dis[x]+dis[y]-2*dis[LCA(x,y)]); } } return 0; }