Codeforces 832 D Misha, Grisha and Underground

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 }

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

时间: 2024-10-10 04:28:52

Codeforces 832 D Misha, Grisha and Underground的相关文章

Codeforces 832D - Misha, Grisha and Underground

832D - Misha, Grisha and Underground 思路:lca,求两个最短路的公共长度.公共长度公式为(d(a,b)+d(b,c)-d(a,c))/2. 代码: #include<bits/stdc++.h> using namespace std; #define ll long long #define ls rt<<1,l,m #define rs rt<<1|1,m+1,r const int INF=0x3f3f3f3f; const

Codeforces Round #425 (Div. 2) Problem D Misha, Grisha and Underground (Codeforces 832D) - 树链剖分 - 树状数组

Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations connected with n - 1 routes so that each route connects two stations, and it is possible to reach every station from any other. The boys decided to h

Misha, Grisha and Underground CodeForces - 832D (倍增树上求LCA)

Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations connected with n - 1 routes so that each route connects two stations, and it is possible to reach every station from any other. The boys decided to h

【树链剖分】【dfs序】【LCA】【分类讨论】Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground

一棵树,q次询问,每次给你三个点a b c,让你把它们选做s f t,问你把s到f +1后,询问f到t的和,然后可能的最大值是多少. 最无脑的想法是链剖线段树--但是会TLE. LCT一样无脑,但是少一个log,可以过. 正解是分类讨论, 如果t不在lca(s,f)的子树内,答案是dis(lca(s,f),f). 如果t在lca(s,f)的子树内,并且dep(lca(s,t))>dep(lca(f,t)),答案是dis(lca(s,t),f): 否则答案是dis(lca(f,t),f). #in

Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground

题意:给出 一颗树,然后q个询问,每个询问给出3个点,让我们自己选择一个起点一个终点,这条路线上的点标记,问第三个点到终点的最多标记点是多少 思路:第三个点到终点的标记点,肯定是第三个点与起点的最近公共祖先到终点的标记点.我们可以求出三个点的的三种最近公共祖先,取深度最大的点K,然后求K到三个点的距离+1 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e5+10; 4 5 const int DEG=17; 6

[CF832D] Misha, Grisha and Underground

题意:给一棵树,若指定三点(f,s,t),泽先江f到s的每一个点染色,答案为f到t路径上染色点的个数 现在给定多组询问(a,b,c),从中确定(f,s,t)使答案最大 这题考场上我居然想了出来并且1A了2333(人生第一次独立做出D绝对不是它太水) 首先让a,b,c分别作为f,取最大的答案 问题变为:已知f,s,t的位置,如何统计答案 分三类讨论(图中f为红色点,棕色路径为答案) lca(f,s)==lca(f,t) lca(f,t)==lca(s,t) lca(f,s)==lca(s,t) 然

【CodeForces - 501B 】Misha and Changing Handles

Misha and Changing Handles CodeForces原题是英文,这里就直接上中文好了,翻译不是太给力,但是不影响做题 ^▽^ Description  神秘的三角洲里还有一个传说中的谜题等你来解开!三角洲里的小学生小明是个小天才,知天文晓地理还能夜观星象算命,好多疯狂的小朋友都想去请他给自己换个好听的名字.但是天才小明,他总是在思考31维宇宙空间的奥秘,神游天外,所以在给小朋友们敲他们想要的名字的时候,偶尔会取出一些不那么完美的名字.有的小朋友们换了名字以后不太满意,于是它

【CodeForces 504A】Misha and Forest

题 题意 给你代表0到n-1的n个点,然后这n个点有d个相连点,相连点的XOR sum 为s,求所有的边. 分析 知识:a^b^a=b,a^b^b=a. 把相连点为1的i存进队列,i的唯一相连点就是S. 然后得到一条边i到s,对i的相连点S,d--,s^=i,就相当于去掉i这个点. 然后再判断S的相连点d是不是1,是1则进入队列. 直到队列为空. 代码 #include<cstdio> #include<algorithm> #include<queue> #defin

codeforces 501 B Misha and Changing Handles 【map】

题意:给出n个名字变化,问一个名字最后变成了什么名字 先用map顺着做的,后来不对, 发现别人是将变化后的那个名字当成键值来做的,最后输出的时候先输出second,再输出first 写一下样例就好理解了 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7