HDU_2586_How far away ?
Posted edward108
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU_2586_How far away ?相关的知识,希望对你有一定的参考价值。
How far away ?
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 18191 Accepted Submission(s): 7072
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
Source
- LCA模板题
- 这里两种代码,一种离线tarjan一种在线RMQ+ST
1 #include <iostream> 2 #include <string> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <climits> 7 #include <cmath> 8 #include <vector> 9 #include <queue> 10 #include <stack> 11 #include <set> 12 #include <map> 13 using namespace std; 14 typedef long long LL ; 15 typedef unsigned long long ULL ; 16 const int maxn = 1e5 + 10 ; 17 const int inf = 0x3f3f3f3f ; 18 const int npos = -1 ; 19 const int mod = 1e9 + 7 ; 20 const int mxx = 100 + 5 ; 21 const double eps = 1e-6 ; 22 const double PI = acos(-1.0) ; 23 24 /* LCA + ST + RMQ Online */ 25 struct node{ 26 int v, next; 27 LL w; 28 }; 29 node edge[maxn<<1]; 30 int fac[30]; 31 int vis[maxn]; 32 int head[maxn<<1], cnt; 33 int ver[maxn<<1], dep[maxn<<1], first[maxn], tot; 34 int dp[maxn<<1][30]; 35 LL dis[maxn]; 36 void addedge(int x, int y, LL z){ 37 edge[cnt].v=y; 38 edge[cnt].w=z; 39 edge[cnt].next=head[x]; 40 head[x]=cnt++; 41 } 42 void dfs(int u, int d){ 43 tot++; 44 vis[u]=1; 45 ver[tot]=u; 46 dep[tot]=d; 47 first[u]=tot; 48 for(int i=head[u];i!=-1;i=edge[i].next){ 49 int v=edge[i].v; 50 LL w=edge[i].w; 51 if(!vis[v]){ 52 dis[v]=dis[u]+w; 53 dfs(v,d+1); 54 tot++; 55 ver[tot]=u; 56 dep[tot]=d; 57 } 58 } 59 } 60 void ST(int n){ 61 int k=(int)(log((double)n)/log(2.0)); 62 for(int i=1;i<=n;i++) 63 dp[i][0]=i; 64 for(int j=1;j<=k;j++) 65 for(int i=1;i+fac[j]-1<=n;i++){ 66 int pl=dp[i][j-1]; 67 int pr=dp[i+fac[j-1]][j-1]; 68 if(dep[pl]<dep[pr]) 69 dp[i][j]=pl; 70 else 71 dp[i][j]=pr; 72 } 73 } 74 int RMQ(int l, int r){ 75 int k=(int)(log((double)(r-l+1))/log(2.0)); 76 int pl=dp[l][k]; 77 int pr=dp[r-fac[k]+1][k]; 78 if(dep[pl]<dep[pr]) 79 return pl; 80 else 81 return pr; 82 } 83 int LCA(int u, int v){ 84 int x=first[u]; 85 int y=first[v]; 86 if(x>y)swap(x,y); 87 return ver[RMQ(x,y)]; 88 } 89 int T, n, m, u, v; 90 LL w; 91 int main(){ 92 // freopen("in.txt","r",stdin); 93 // freopen("out.txt","w",stdout); 94 for(int i=0;i<30;i++) 95 fac[i]=(1<<i); 96 while(~scanf("%d",&T)){ 97 while(T--){ 98 scanf("%d %d",&n,&m); 99 cnt=0; 100 memset(head,-1,sizeof(head)); 101 memset(vis,0,sizeof(vis)); 102 for(int i=1;i<n;i++){ 103 scanf("%d %d %lld",&u,&v,&w); 104 addedge(u,v,w); 105 addedge(v,u,w); 106 } 107 dis[1]=0; 108 tot=0; 109 dfs(1,1); 110 ST(tot); 111 while(m--){ 112 scanf("%d %d",&u,&v); 113 printf("%lld\n",dis[u]+dis[v]-2*dis[LCA(u,v)]); 114 } 115 } 116 } 117 return 0; 118 }
1 #include <iostream> 2 #include <string> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <climits> 7 #include <cmath> 8 #include <vector> 9 #include <queue> 10 #include <stack> 11 #include <set> 12 #include <map> 13 using namespace std; 14 typedef long long LL ; 15 typedef unsigned long long ULL ; 16 const int maxn = 1e5 + 10 ; 17 const int inf = 0x3f3f3f3f ; 18 const int npos = -1 ; 19 const int mod = 1e9 + 7 ; 20 const int mxx = 100 + 5 ; 21 const double eps = 1e-6 ; 22 const double PI = acos(-1.0) ; 23 24 /* Tarjan Offline */ 25 struct node{ 26 int v, next; 27 LL w; 28 }; 29 node edge[maxn<<1], ask[maxn<<1]; 30 int head0[maxn<<1], cnt0; 31 int head1[maxn<<1], cnt1; 32 int vis[maxn], fa[maxn]; 33 LL ans[300], dis[maxn]; 34 void addedge(int x, int y, LL z, int flag){ 35 if(flag){ 36 ask[cnt1].v=y; 37 ask[cnt1].w=z; 38 ask[cnt1].next=head1[x]; 39 head1[x]=cnt1++; 40 }else{ 41 edge[cnt0].v=y; 42 edge[cnt0].w=z; 43 edge[cnt0].next=head0[x]; 44 head0[x]=cnt0++; 45 } 46 } 47 int find(int u){ 48 if(u==fa[u]) 49 return u; 50 else 51 return fa[u]=find(fa[u]); 52 // return u==fa[u]?u:find(fa[u]); 53 } 54 void Union(int x, int y){ 55 int fx=find(x); 56 int fy=find(y); 57 if(fx!=fy) 58 fa[fy]=fx; 59 } 60 void Tarjan(int u){ 61 vis[u]=1; 62 fa[u]=u; 63 for(int i=head1[u];i!=-1;i=ask[i].next){ 64 int v=ask[i].v; 65 if(vis[v]){ 66 int lca=find(v); 67 int id=ask[i].w; 68 ans[id]=dis[u]+dis[v]-2*dis[lca]; 69 } 70 } 71 for(int i=head0[u];i!=-1;i=edge[i].next){ 72 int v=edge[i].v; 73 LL w=edge[i].w; 74 if(!vis[v]){ 75 dis[v]=dis[u]+w; 76 Tarjan(v); 77 Union(u,v); 78 } 79 } 80 } 81 int T, n, m, u, v; 82 LL w; 83 int main(){ 84 // freopen("in.txt","r",stdin); 85 // freopen("out.txt","w",stdout); 86 while(~scanf("%d",&T)){ 87 while(T--){ 88 scanf("%d %d",&n,&m); 89 cnt0=0; 90 cnt1=0; 91 memset(head0,-1,sizeof(head0)); 92 memset(head1,-1,sizeof(head1)); 93 memset(vis,0,sizeof(vis)); 94 for(int i=1;i<n;i++){ 95 scanf("%d %d %lld",&u,&v,&w); 96 addedge(u,v,w,0); 97 addedge(v,u,w,0); 98 } 99 for(int i=1;i<=m;i++){ 100 scanf("%d %d",&u,&v); 101 addedge(u,v,(LL)i,1); 102 addedge(v,u,(LL)i,1); 103 } 104 dis[1]=0; 105 Tarjan(1); 106 for(int i=1;i<=m;i++) 107 printf("%lld\n",ans[i]); 108 } 109 } 110 return 0; 111 }
以上是关于HDU_2586_How far away ?的主要内容,如果未能解决你的问题,请参考以下文章
hdu 2586 How far away?(树链剖分+前缀和)