码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 832 D Misha, Grisha and Underground

时间:2018-02-27 23:44:54      阅读:230      评论:0      收藏:0      [点我收藏+]

标签:codeforce   def   记录   一个   air   can   pos   最大的   i++   

Misha, Grisha and Underground

题意:Misha 和 Grisha 是2个很喜欢恶作剧的孩子, 每天早上 Misha 会从地铁站 s 通过最短的路到达地铁站 f, 并且在每个地铁站上都写上一句话, 然后Grisha 再从地铁站 t 通过最短的路到达地铁站 f, 并且记录下路途上被Misha写上字的地铁站数目,并且当天晚上会人会将地铁站清理干净,不会干扰第二天的计数, 现在给你3个地铁站 a, b, c, 现在求Misha记录的数目最大能是多少。

代码:求出Lca(a,b) Lca(a,c) Lca(b,c) 再找到深度最大的那个点, 我门可以通过画图发现 这个点是一个3叉路口, 从这个路口往每一地铁站走的路都是有效长度,最后找到有效长度就是答案了。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 #define ULL unsigned LL
 5 #define fi first
 6 #define se second
 7 #define lson l,m,rt<<1
 8 #define rson m+1,r,rt<<1|1
 9 #define max3(a,b,c) max(a,max(b,c))
10 const int INF = 0x3f3f3f3f;
11 const LL mod = 1e9+7;
12 typedef pair<int,int> pll;
13 const int N = 1e5+5;
14 struct Node{
15     int to;
16     int nt;
17 }e[N<<1];
18 int head[N], anc[20][N], deep[N];
19 int tot = 0;
20 void add(int u, int v){
21     e[tot].to = v;
22     e[tot].nt = head[u];
23     head[u] = tot++;
24 }
25 void dfs(int u, int o){
26     deep[u] = deep[o] + 1;
27     for(int i = head[u]; ~i; i = e[i].nt){
28         if(o != e[i].to){
29             anc[0][e[i].to] = u;
30             for(int j = 1; j < 20; j++) anc[j][e[i].to] = anc[j-1][anc[j-1][e[i].to]];
31             dfs(e[i].to,u);
32         }
33     }
34 }
35 int lca(int u, int v){
36     if(deep[u] < deep[v]) swap(u, v);
37     for(int i = 19; i >= 0; i--) if(deep[v] <= deep[anc[i][u]]) u = anc[i][u];
38     if(u == v) return v;
39     for(int i = 19; i >= 0; i--) if(anc[i][u] != anc[i][v]) u = anc[i][u], v = anc[i][v];
40     return anc[0][u];
41 }
42 int dis(int u, int v)
43 {
44     return deep[u]+deep[v]-2*deep[lca(u,v)];
45 }
46 int main(){
47     int n, m, v;
48     scanf("%d%d", &n, &m);
49     memset(head, -1, sizeof(head));
50     for(int i = 2; i <= n; i++){
51         scanf("%d", &v);
52         add(i,v);
53         add(v,i);
54     }
55     dfs(1,0);
56     int a, b, c;
57     for(int i = 1; i <= m; i++){
58         scanf("%d%d%d",&a,&b,&c);
59         int t1 = lca(a, b), t2 = lca(b,c), t3 = lca(a,c);
60         //cout << t1 <<‘ ‘ << t2 << ‘ ‘ << t3 << endl;
61         if(deep[t1] < deep[t2]) t1 = t2;
62         if(deep[t1] < deep[t3]) t1 = t3;
63         int ans = max3(dis(t1,a), dis(t1,b), dis(t1,c));
64         printf("%d\n",ans+1);
65     }
66     return 0;
67 }

 

Codeforces 832 D Misha, Grisha and Underground

标签:codeforce   def   记录   一个   air   can   pos   最大的   i++   

原文地址:https://www.cnblogs.com/MingSD/p/8480921.html

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