zoukankan      html  css  js  c++  java
  • CDOJ 1437 谭松松的旅游计划 Label:倍增LCA && 最短路

    谭松松的旅游计划

    Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
     

    谭松松是一个爱旅游的人,他非常的热爱旅游,即便身体被掏空也要坚持旅游。喵蛤王国由N个城市组成,由N-1条道路连通,每条道路长度为ci,使得任意两座城市都能相互到达。谭松松有M个旅游计划,每个旅游计划有一个起点ai,一个终点bi,所以谭松松想知道,对于每个旅游计划,从起点到终点的最短路长度为多少?

    Input

    第一行两个整数N(2≤N≤100000,),M(1≤M≤100000),表示城市个数,谭松松的旅游计划个数。

    接下来N-1行,每行三个整数li,ri,ci(1≤ci≤10000),表示li号城市和ri号城市之间有一条长度为ci的道路。

    接下来M行,每行两个整数ai,bi表示旅游计划的起点和终点。

    Output

    输出M行,表示每个旅游计划的最短距离。

    Sample input and output

    Sample InputSample Output
    7 6
    1 2 5
    1 3 4
    3 7 7
    2 4 4
    2 5 3
    5 6 2
    1 2
    4 7
    6 3
    3 2
    5 4
    7 6
    5
    20
    14
    9
    7
    21 

    代码

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<vector>
     6 #include<queue>
     7 #define ll long long
     8 const int MAXN=200005;
     9 using namespace std;
    10 
    11 int N,M;
    12 int pa[30][MAXN],depth[MAXN],vis[MAXN];
    13 ll cost[30][MAXN];//注意long long 
    14 vector<int> G[MAXN],c[MAXN];
    15 
    16 void dfs(int x,int pre,int d){
    17     vis[x]=1;
    18     depth[x]=d;
    19     pa[0][x]=pre;
    20     for(int i=0;i<G[x].size();i++){
    21         int to=G[x][i];
    22         if(!vis[to]){
    23             cost[0][to]=c[x][i];
    24             dfs(to,x,d+1);
    25         }
    26     }
    27 }
    28 
    29 void init_lca(){
    30     memset(pa,-1,sizeof(pa));
    31     
    32     dfs(1,-1,0);
    33     for(int k=0;k<=25;k++){
    34         for(int i=1;i<=N;i++){
    35             if(pa[k][i]>0){
    36                 pa[k+1][i]=pa[k][ pa[k][i] ];
    37                 cost[k+1][i]=cost[k][i]+cost[k][ pa[k][i] ];
    38 //                cout<<cost[k+1][i]<<endl;
    39             }
    40         }
    41     }
    42 }
    43 
    44 ll lca(int u,int v){//long long
    45     ll sum=0;
    46     if(depth[u]>depth[v]) swap(u,v);
    47 //    cout<<u<<v<<endl;
    48     for(int k=0;k<25;k++){
    49         if((depth[v]-depth[u])>>k&1){
    50             sum+=cost[k][v];
    51             v=pa[k][v];//这两行不能换..... 
    52 //            cout<<cost[k][u]<<endl;
    53         }
    54     }
    55     
    56     if(u==v) return sum;
    57     for(int k=25;k>=0;k--){
    58         if(pa[k][u]!=pa[k][v]){
    59             sum+=(cost[k][u]+cost[k][v]);
    60             u=pa[k][u];
    61             v=pa[k][v];
    62         }
    63     }
    64     sum+=(cost[0][v]+cost[0][u]);
    65     return sum;
    66 }
    67 
    68 int main(){
    69 //    freopen("01.in","r",stdin);
    70     scanf("%d%d",&N,&M);
    71     for(int i=1;i<N;i++){
    72         int x,y,cc;
    73         scanf("%d%d%d",&x,&y,&cc);
    74         G[x].push_back(y);
    75         G[y].push_back(x);
    76         c[x].push_back(cc);
    77         c[y].push_back(cc);
    78     }
    79     init_lca();
    80     while(M--){
    81         int a,b;
    82         scanf("%d%d",&a,&b);
    83         printf("%lld
    ",lca(a,b));//此处用cout会T!!! 
    84     }
    85     return 0;
    86 }

    Line50 和Line51换了会爆炸

    然后83用cout会爆炸,直接T掉

    输出1万次就得用printf

    cout也就比printf慢几千倍吧~

    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!
  • 相关阅读:
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
  • 原文地址:https://www.cnblogs.com/radiumlrb/p/5929006.html
Copyright © 2011-2022 走看看