码迷,mamicode.com
首页 > 编程语言 > 详细

C++之路进阶——LCA

时间:2016-01-10 14:21:37      阅读:314      评论:0      收藏:0      [点我收藏+]

标签:

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     }  

 

 

C++之路进阶——LCA

标签:

原文地址:http://www.cnblogs.com/grhyxzc/p/5118365.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!