• C++之路进阶——codevs1036(商务旅行)


    1036 商务旅行 

    题目描述 Description

    某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间。

    假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任意两个城镇之间如果有直连道路,在他们之间行驶需要花费单位时间。该国公路网络发达,从首都出发能到达任意一个城镇,并且公路网络不会存在环。

    你的任务是帮助该商人计算一下他的最短旅行时间。

    输入描述 Input Description

    输入文件中的第一行有一个整数N,1<=n<=30 000,为城镇的数目。下面N-1行,每行由两个整数a 和b (1<=a, b<=n; a<>b)组成,表示城镇a和城镇b有公路连接。在第N+1行为一个整数M,下面的M行,每行有该商人需要顺次经过的各城镇编号。

    输出描述 Output Description

        在输出文件中输出该商人旅行的最短时间。

    样例输入 Sample Input
    5
    1 2
    1 5
    3 5
    4 5
    4
    1
    3
    2
    5
    样例输出 Sample Output

    7

    思路:

      裸lca。。。。,模板题。不懂看代码。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<vector>
     5 #include<algorithm>
     6 #define maxn 30010
     7 
     8 using namespace std;
     9 
    10 vector<int> s[30010];
    11 int fa[maxn][100],deep[maxn],n,m;
    12 
    13 void  getdeep(int k,int d)
    14     {
    15         deep[k]=d;
    16         for (int i=1;(1<<i)<=deep[k];i++)
    17           fa[k][i]=fa[fa[k][i-1]][i-1];
    18         for (int i=0;i<s[k].size();i++)
    19           {
    20               if (!deep[s[k][i]])
    21                  {
    22                       fa[s[k][i]][0]=k;
    23                       getdeep(s[k][i],d+1);
    24                  }
    25           } 
    26     }
    27     
    28 int lca(int x,int y)
    29   {
    30       if (deep[x]<deep[y]) swap(x,y);
    31       int t=deep[x]-deep[y];
    32       for (int i=0;i<20;i++)
    33        if ((1<<i)&t) x=fa[x][i];      
    34       for (int i=20;i>=0;i--)
    35          {
    36                if (fa[x][i]!=fa[y][i])
    37                    {
    38                          x=fa[x][i];
    39                          y=fa[y][i];
    40                    }
    41          } 
    42     if (x==y)    return x;
    43     return fa[x][0]; 
    44   }
    45   
    46 int main()
    47   {
    48       scanf("%d",&n);
    49       for (int i=0;i<n-1;i++)
    50         {
    51             int x,y;
    52             scanf("%d%d",&x,&y);
    53             s[y].push_back(x);
    54             s[x].push_back(y);
    55         }
    56     getdeep(1,1);   
    57     scanf("%d",&m);    
    58     int anss=0;
    59     int a=1,b;
    60     for (int i=0;i<m;i++)
    61          {
    62              scanf("%d",&b);
    63               anss+=deep[a]+deep[b]-2*deep[lca(a,b)];
    64               a=b;
    65                  }
    66     printf("%d",anss);
    67     return 0;                     
    68     }  
  • 相关阅读:
    实现垂直居中
    三栏布局(双飞翼布局和圣杯布局)
    JavaScript执行机制
    使用vue-cil搭建项目
    格式化上下文formatting contexts
    定位体系(定位机制)
    CSS盒子模型
    可视化格式模型(visual formatting model)
    CSS布局开篇
    Linux之vi三种模式常用操作
  • 原文地址:https://www.cnblogs.com/grhyxzc/p/5118365.html
Copyright © 2020-2023  润新知