1. 程式人生 > >HDU_2586_How far away ?

HDU_2586_How far away ?

ane java sig rep tarjan 1.0 tle lin split

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.

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 ECJTU 2009 Spring Contest
  • 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 ?