CF 690C3. Brain Network (hard) from Helvetic Coding Contest 2016 online mirror (teams, unrated)
题目描述
Brain Network (hard) 这个问题就是给出一个不断加边的树,保证每一次加边之后都只有一个连通块(每一次连的点都是之前出现过的),问每一次加边之后树的直径。
算法
每一次增加一条边之后,树的直径长度要么不变,要么会增加1,并且如果树的直径长度增加1了,新的直径的端点其中一个必然是新增的点,而另一个是原来直径的某个端点。关于为什么可以这样做,在Quora上有个回答解释地不错,可以参考。
实现
所以这个问题其实就是要计算树上任意两个点的距离,LCA可以很轻松地处理。
可以一次性先把数据都读完,建树,因为每一次询问,后面加入的边不会对当前询问造成影响。
如果用二进制祖先那种搞法来算LCA的话,也可以每读一个新增点就去算一下,相当于是把原来的过程给拆开了。
下面是我的代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
const int N = 223456;
struct Edge {
int to, next;
} edge[N << 1];
int idx = 1, head[N];
void addEdge(int u, int v) {
edge[++idx].to = v;
edge[idx].next = head[u];
head[u] = idx;
}
void init() {
memset(head, 0, sizeof(head));
idx = 1;
}
int par[N][21];
int dep[N];
void dfs(int u, int fa, int d) {
dep[u] = d;
for (int k = head[u]; k; k = edge[k].next) {
int v = edge[k].to;
if (v == fa) continue;
par[v][0] = u;
dfs(v, u, d + 1);
}
}
void calc(int n) {
for (int i = 1; i <= 20; i++) {
for (int j = 1; j <= n; j++) {
par[j][i] = par[par[j][i - 1]][i - 1];
}
}
}
int kthA(int u, int k) {
for (int i = 20; i >= 0; i--) {
if (k >= (1 << i)) {
k -= (1 << i);
u = par[u][i];
}
}
return u;
}
int lca(int u, int v) {
if (dep[u] < dep[v])swap(u, v);
u = kthA(u, dep[u] - dep[v]);
if (u == v)return u;
for (int i = 20; i >= 0; i--) {
if (par[u][i] == par[v][i])continue;
u = par[u][i];
v = par[v][i];
}
return par[u][0];
}
bool update(int u, int v, int &k) {
int a = lca(u, v);
int d = dep[u] + dep[v] - 2 * dep[a];
if (d > k) {
k = d;
return true;
}
return false;
}
int a[N];
int main() {
int n;
scanf("%d", &n);
int u = 1, v = 1, cur = 0;
init();
for (int i = 2; i <= n; i++) {
scanf("%d", a + i);
addEdge(a[i], i);
}
dfs(1, -1, 0);
calc(n);
for (int i = 2; i <= n; i++) {
int nv = v;
if (update(u, i, cur)) {
nv = i;
}
if (update(v, i, cur)) {
u = v;
nv = i;
}
v = nv;
printf("%d ", cur);
}
puts("");
return 0;
}
CF 690C3. Brain Network (hard) from Helvetic Coding Contest 2016 online mirror (teams, unrated)的更多相关文章
- Helvetic Coding Contest 2016 online mirror C1
Description One particularly well-known fact about zombies is that they move and think terribly slow ...
- Helvetic Coding Contest 2016 online mirror A1
Description Tonight is brain dinner night and all zombies will gather together to scarf down some de ...
- Helvetic Coding Contest 2016 online mirror C2
Description Further research on zombie thought processes yielded interesting results. As we know fro ...
- Helvetic Coding Contest 2017 online mirror (teams allowed, unrated)
G. Fake News (easy) time limit per test 1 second memory limit per test 256 megabytes input standard ...
- Helvetic Coding Contest 2017 online mirror (teams allowed, unrated) J
Description Heidi's friend Jenny is asking Heidi to deliver an important letter to one of their comm ...
- Helvetic Coding Contest 2016 online mirror F1
Description Heidi has finally found the mythical Tree of Life – a legendary combinatorial structure ...
- Helvetic Coding Contest 2016 online mirror B1
Description The zombies are gathering in their secret lair! Heidi will strike hard to destroy them o ...
- Helvetic Coding Contest 2016 online mirror D1
Description "The zombies are lurking outside. Waiting. Moaning. And when they come..." &qu ...
- Helvetic Coding Contest 2017 online mirror (teams allowed, unrated) M
Description The marmots have prepared a very easy problem for this year's HC2 – this one. It involve ...
随机推荐
- 【2-23】分支语句(switch…case)及循环语句
Switch-case分支语句与if语句作用相同,但需将情况都罗列出比较麻烦所以不常用. 其基本结构是: Switch(一个变量值) { Case 值1:要执行的代码段:break; Case 值2: ...
- 从零开始部署小型企业级虚拟桌面 -- Vmware Horizon View 6 For Linux VDI -- 概念简介
什么是桌面虚拟化? 桌面虚拟化有很多概念,此处谈论的,是指的一般企业使用的“服务器 + 虚拟机 + 云终端”的方式来实现的. 桌面虚拟化的原理是什么? 桌面虚拟化看上去高大上,实际上原理非常的简单.拿 ...
- Unity中溶解shader的总结
在实际的游戏工程中,经常美术和策划会提出溶解的表现要求.比如子弹在飞行的时候,弹道不断的消融:角色受到大型炮弹的攻击,在击飞的时候不断的消融等等诸如此类的表现.一般的消融都是结合粒子系统来实现,通过给 ...
- [.net 面向对象程序设计深入](26)实战设计模式——使用Ioc模式(控制反转或依赖注入)实现松散耦合设计(1)
[.net 面向对象程序设计深入](26)实战设计模式——使用IoC模式(控制反转或依赖注入)实现松散耦合设计(1) 1,关于IOC模式 先看一些名词含义: IOC: Inversion of con ...
- Spring-boot中使用@ConditionalOnExpression注解,在特定情况下初始化bean
想要实现的功能: 我想在配置文件中设置一个开关,enabled,在开关为true的时候才实例化bean,进行相关业务逻辑的操作. 具体实现: 1:要实例化的bean 2. 配置类 代码: 想要实例化的 ...
- 解锁redis锁的正确姿势
解锁redis锁的正确姿势 redis是php的好朋友,在php写业务过程中,有时候会使用到锁的概念,同时只能有一个人可以操作某个行为.这个时候我们就要用到锁.锁的方式有好几种,php不能在内存中用锁 ...
- 使用MyBatis对数据库中表实现CRUD操作(二)
一.使用MyBatis对表实现CRUD操作 1.定义sql映射 userMapper.xml <?xml version="1.0" encoding="UTF-8 ...
- IOS开发创建开发证书及发布App应用(八)——使用Application Loader工具上传应用
8.使用Application Loader工具上传应用 继续第七步在iTunes所创建的应用,打开应用,如下图 点击详情按钮进去之后,单击右上角Ready to Upload Binary按钮,如下 ...
- CSS核心属性
学习目标 1.css浮动属性详解 2.Css文本属性 3.Css列表属性 4.Css背景属性 5.Css边框属性 一.Css浮动属性详解 无论多么复杂的布局,其基本出发点均是:"如何在一行显 ...
- Excel公式-求最低价网站名字
p{ font-size: 15px; } .alexrootdiv>div{ background: #eeeeee; border: 1px solid #aaa; width: 99%; ...