题目描述

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)的更多相关文章

  1. Helvetic Coding Contest 2016 online mirror C1

    Description One particularly well-known fact about zombies is that they move and think terribly slow ...

  2. Helvetic Coding Contest 2016 online mirror A1

    Description Tonight is brain dinner night and all zombies will gather together to scarf down some de ...

  3. Helvetic Coding Contest 2016 online mirror C2

    Description Further research on zombie thought processes yielded interesting results. As we know fro ...

  4. 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 ...

  5. 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 ...

  6. Helvetic Coding Contest 2016 online mirror F1

    Description Heidi has finally found the mythical Tree of Life – a legendary combinatorial structure ...

  7. Helvetic Coding Contest 2016 online mirror B1

    Description The zombies are gathering in their secret lair! Heidi will strike hard to destroy them o ...

  8. Helvetic Coding Contest 2016 online mirror D1

    Description "The zombies are lurking outside. Waiting. Moaning. And when they come..." &qu ...

  9. 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 ...

随机推荐

  1. 【2017-03-12】SQL Sever 子查询、聚合函数

    一.子查询 子查询:把一条查询语句,当做值来使用子句的查询结果必须是一列子句可以返回多行数据,但必须是一列 子句返回的值为一个值的时候: 例如: 我只知道c026这个编号,我要查询比这个车价格低的全部 ...

  2. 二叉堆 C++实现

    #ifndef __BINARY_HEAP_H__ #define __BINARY_HEAP_H__ #include <iostream> #include <vector> ...

  3. 3360: [Usaco2004 Jan]算二十四

    3360: [Usaco2004 Jan]算二十四 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6  Solved: 6[Submit][Statu ...

  4. React-Native 之 项目实战(二)

    前言 本文有配套视频,可以酌情观看. 文中内容因各人理解不同,可能会有所偏差,欢迎朋友们联系我. 文中所有内容仅供学习交流之用,不可用于商业用途,如因此引起的相关法律法规责任,与我无关. 如文中内容对 ...

  5. 关于连接数据库的T-SQL语句中的一种小技巧

    (编程生活中,我们经常会用到数据库.然后在通过T-SQL语句来对数据库进行操作的时候,遇到很多麻烦.话说昨天我就被困扰了一天.明明这个T-sql插数据的语句放在数据库运行的时候没有问题,到了java代 ...

  6. GitHub中最强大的iOS Notifications和AlertView框架,没有之一!

    FFToast是一个非常强大的iOS message notifications和AlertView扩展.它可以很容易实现从屏幕顶部.屏幕底部和屏幕中间弹出一个通知.你可以很容易的自定义弹出的View ...

  7. 日期控件My97DatePicker的使用

    一. 简介 1. 简介 目前的版本是:4.8 2. 注意事项 My97DatePicker目录是一个整体,不可破坏里面的目录结构,也不可对里面的文件改名,可以改目录名 My97DatePicker.h ...

  8. Unity 3D Framework Designing(6)——设计动态数据集合ObservableList

    什么是 『动态数据集合』 ?简而言之,就是当集合添加.删除项目或者重置时,能提供一种通知机制,告诉UI动态更新界面.有经验的程序员脑海里迸出的第一个词就是 ObservableCollection.没 ...

  9. Sass实战 sass官网

    Sass实战 sass官网 1.相关视频教程:http://pan.baidu.com/s/1eSl8bUa 1.1我的项目源码:http://pan.baidu.com/s/1dFmqbyp 1.2 ...

  10. 庆祝POPTEST签约企业培训

    庆祝POPTEST签约企业培训 POPTEST与众多培训企业进行技术PK,由于企业认可POPTEST的技术实力,从众多竞争对手中脱颖而出,成功中标清华控股子公司性能测试培训.