How far away ?+hdu+最近公共祖先
2014-09-30 09:28
337 查看
How far away ?Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5713 Accepted Submission(s): 2153 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. 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 解决方案:最近公共祖先,可记录每个点到根的距离,然后两点之间的最短距离就是dist[u]+dist[v]-2*dist[LCA(u,v)];code:#include <iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=50000; int ehead[maxn],qhead[maxn],fa[maxn]; int F[maxn],T[maxn]; int du[maxn]; int dist[maxn]; bool vis[maxn]; int k,n,m; struct edge { int to,next; int dis; } E[maxn*2],Q[maxn*2]; void addedge(int from,int to,int v) { E[k].to=to; E[k].dis=v; E[k].next=ehead[from]; ehead[from]=k++; } void addquery(int from,int to) { Q[k].to=to; Q[k].dis=0; Q[k].next=qhead[from]; qhead[from]=k++; } int Root(int u) { return u!=fa[u]?fa[u]=Root(fa[u]):u; } void Unoin(int u,int v) { int us=Root(u); int vs=Root(v); if(us!=vs) { fa[vs]=us; } } void tarjan(int u) { vis[u]=true; for(int i=qhead[u]; i!=-1; i=Q[i].next) { int v=Q[i].to; if(vis[v]) { int LCA=Root(v); Q[i].dis=dist[u]+dist[v]-2*dist[LCA]; for(int j=qhead[v]; j!=-1; j=Q[j].next) { if(Q[j].to==u) { Q[j].dis=dist[u]+dist[v]-2*dist[LCA]; break; } } } } for(int i=ehead[u]; i!=-1; i=E[i].next) { int v=E[i].to; if(vis[v]) continue; dist[v]=dist[u]+E[i].dis; tarjan(v); Unoin(u,v); } } void init() { for(int i=1; i<=n; i++) { fa[i]=i; } memset(vis,0,sizeof(vis)); memset(ehead,-1,sizeof(ehead)); memset(qhead,-1,sizeof(qhead)); memset(dist,0,sizeof(dist)); memset(du,0,sizeof(du)); k=0; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); init(); for(int i=0; i<n-1; i++) { int from,to,v; scanf("%d%d%d",&from,&to,&v); du[to]++; addedge(from,to,v); addedge(to,from,v); } k=0; for(int i=0; i<m; i++) { scanf("%d%d",&F[i],&T[i]); addquery(F[i],T[i]); addquery(T[i],F[i]); } for(int i=1; i<=n; i++) { if(du[i]==0) { //cout<<i<<endl; tarjan(i); } } for(int i=0; i<m; i++) { for(int v=qhead[F[i]]; v!=-1; v=Q[v].next) { int to=Q[v].to; if(to==T[i]) { printf("%d\n",Q[v].dis); break; } } } } return 0; } |
相关文章推荐
- HDU 2586 How far away ? (LCA最近公共祖先)
- [HDU 2586] How far away ? 最近公共祖先
- HDU2586 How far away ?(最近公共祖先lca,离线Tarjan,最短路)
- hdu 2586 How far away ? 最近公共祖先lca 在线算法(倍增法)/离线算法(Tarjan算法)
- hdu 2586 How far away ?(LCA:最近公共祖先)
- HDU 2586 How far away ?(LCA模板 最近公共祖先啊)
- hdu 2586 How far away ?(最近公共祖先)
- HDU 2586 How far away ? (Lca最近公共祖先 在线算法)
- HDU 2586 How far away ? 最近公共祖先LCA
- 学习记录4:LCA (最近公共祖先)(hdu 2586 How far away?)
- HDU 2586 How far away ? Tarjan 离线最近公共祖先
- hdu 2586 How far away ?【最近公共祖先】
- hdu 2586 How far away ?(离线求最近公共祖先)
- 【LCA最近公共祖先】HDU 2586 How far away ?
- hdu 2586 How far away ? LCA 最近公共祖先
- hdu2586-How far away ?(最近公共祖先(LCA),离线Tarjan算法)
- HDU2586 How far away ?(LCA求最近公共祖先)
- [HDOJ2586]How far away?(最近公共祖先, 离线tarjan, 并查集)
- [HDOJ2586]How far away?(最近公共祖先 瞎写)
- HDU 2586-How far away(最近公共祖先LCA)