Codeforces Round #425 (Div. 2)D. Misha, Grisha and Underground(LCA)
来源:互联网 发布:c语言快速排序算法代码 编辑:程序博客网 时间:2024/05/17 03:34
题目链接
http://codeforces.com/contest/832/problem/D
题目大意
给你一棵树, 以及q次询问,每次询问给你a,b, c三个节点
你可以将这三个节点任意(一一对应)定为s, f, t节点,
然后进行以下操作
从s–>f跑最短路,并标记路上的点
从t–>f跑最短路,统计刚刚标记的点的个数
(每次询问过后标记的点会被清空)
问你每次询问统计出的标记的点个数的最大值
思路
树上最短路我们可以用LCA(两个节点最近的公共祖先)进行计算
我们用ab表示lca(a, b), ac = lca(a, c), bc = lca(b, c)
这样必定会有两个值相等, 如下图所示
那么最大值必然在三条路之间
a–>ab
b–>ab
c–>ab
至于路径的计算,lca计算过程中有一个deep数组,用于记录节点所在深度,那么a–>ab距离 = deep[a] - deep[ab], 以此类推
代码
#include<bits/stdc++.h>using namespace std;const int M = 1e5 + 5;vector<int>g[M];int root;int parent[20][M];int dep[M];int n, q;void dfs(int v, int p, int d){ parent[0][v] = p; dep[v] = d; for(int i=0; i<g[v].size(); ++i) { if(g[v][i]!=p) dfs(g[v][i], v, d+1); }}void init(){ for(int k = 0; k < 20-1; ++ k) { for(int v = 1; v <= n; ++ v) { if(parent[k][v] < 0) parent[k+1][v] = -1; else { parent[k+1][v] = parent[k][parent[k][v]]; } } }}int getlca(int u, int v){ if(dep[u] > dep[v]) swap(u, v); int ans = 0; for(int k = 0; k < 20; ++ k) { if((dep[v] - dep[u]) >> k & 1) { v = parent[k][v]; } } if(u != v) { for(int k = 20 - 1; k >= 0; -- k) { if(parent[k][u] != parent[k][v]) { u = parent[k][u], v = parent[k][v]; } } u = parent[0][u]; return u; } return u;}int solve(int a, int b, int c, int ab, int ac){ int mx = 0; mx = max(dep[a] - dep[ab] + 1, dep[b] - dep[ab] + 1); mx = max(mx, dep[ab] - dep[ac] + dep[c] - dep[ac] + 1); return mx;}int main(){ scanf("%d%d", &n, &q); for(int i=1; i<n; ++i) { int tmp; scanf("%d", &tmp); g[i+1].push_back(tmp); g[tmp].push_back(i+1); } dfs(1, -1, 1); init(); for(int i=0; i<q; ++i) { int a, b, c, ans = 0; scanf("%d%d%d", &a, &b, &c); int ab = getlca(a, b); int bc = getlca(b, c); int ac = getlca(a, c); int mx = max(dep[ab], max(dep[bc], dep[ac])); if(dep[ab] == mx) { ans = solve(a, b, c, ab, ac); } else if(dep[ac] == mx) { ans = solve(a, c, b, ac, ab); } else if(dep[bc] == mx) { ans = solve(b, c, a, bc, ab); } printf("%d\n", ans); } return 0;}
阅读全文
0 0
- Codeforces Round #425 (Div. 2)D. Misha, Grisha and Underground(LCA)
- Codeforces Round #425 (Div. 2)D. Misha, Grisha and Underground
- Codeforces Round #425 (Div. 2) D.Misha, Grisha and Underground
- Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground
- Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground LCA模版
- Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground LCA
- codeforces D. Misha, Grisha and Underground(LCA)
- Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground 最近公共祖先
- CodeForces 832D Round #425 D Misha, Grisha and Underground :LCA求树上路径长度
- CF #425 DIV2 D. Misha, Grisha and Underground(LCA)
- 【Lca 倍增】codeforces 832D Misha, Grisha and Underground
- Codeforces 832D-Misha, Grisha and Underground(LCA)
- Codeforces 832D. Misha, Grisha and Underground【LCA】
- Codeforces 832D Misha, Grisha and Underground【LCA】
- codeforces 832D Misha, Grisha and Underground 倍增lca
- D. Misha, Grisha and Underground(LCA 倍增)
- CF 832D Misha, Grisha and Underground(Tree+lca)
- codeforces 832D——Misha, Grisha and Underground(LCA)
- linux中虚拟机的管理
- java自学-流程控制
- HDU 3594 Cactus (仙人掌图、Tarjan)
- 绝对强大的三大linux指令:ar, nm, objdump
- ssh中与前端的json数据交换
- Codeforces Round #425 (Div. 2)D. Misha, Grisha and Underground(LCA)
- 代码组装Json字符串
- 跨数据库查询
- SQO2008配置管理工具服务显示远程过程调用失败 0x800706be
- 线上迁移mysql 的datadir
- C++的单例模式与线程安全单例模式(懒汉/饿汉)
- ccf认证数位之和
- Python os._exit() sys.exit() exit()区别
- 马尔科夫过程详解