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 ...
 
随机推荐
- 图形化代码阅读工具——Scitools Understand
			
Scitools出品的Understand 2.0.用了很多年了,比Source Insight强大很多.以前的名字叫Understand for C/C++,Understand for Java, ...
 - 3384/1750: [Usaco2004 Nov]Apple Catching 接苹果
			
3384/1750: [Usaco2004 Nov]Apple Catching 接苹果 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 18 Solv ...
 - UITableView 编辑模式(增加-删除-移动---自定义左滑 title)
			
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typica ...
 - wx模块小实例
			
功能介绍: 查询数据库表数据,提取数据并显示 main.py(执行文件) #coding:gbk __author__ = 'Hito' import querySmscode import wx c ...
 - 机器学习基石 4 Feasibility of Learning
			
机器学习基石 4 Feasibility of Learning Learning is Impossible? 机器学习:通过现有的训练集 \(D\) 学习,得到预测函数 \(h(x)\) 使得它接 ...
 - Selenium自动化脚本开发总结
			
Selenium Selenium 是ThoughtWorks专门为Web应用程序编写的一个验收测试工具. Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE.Mo ...
 - 【树莓派】Linux应用相关:自动删除n天前日志
			
linux是一个很能自动产生文件的系统,日志.邮件.备份等.虽然现在硬盘廉价,我们可以有很多硬盘空间供这些文件浪费,让系统定时清理一些不需要的文件很有一种爽快的事情.不用你去每天惦记着是否需要清理日志 ...
 - NOI全国赛(2001)--食物链
			
今天写了道并查集的题,看来并查集的题刷少了,,,,,用法好神奇啊!!!开三倍并查集 用i表示自己,i+n存天敌,i+2*n存可以克制de,再逻辑判断一下即可. 所以,要意识到并查集的分类处理可以开不同 ...
 - Chrome 开发工具 Workspace 使用
			
前端开发中我们经常要在浏览器中做一些细节调整,比如对 CSS 的微调,最快的方式当然是直接在 Chrome 的开发者工具中调整,但问题在于在控制台中调试好的数值我们还需要再在 CSS 源码中再写一次, ...
 - 【已解决】Windows下 MySQL大小写敏感 解决方案及分析
			
Windows下 MySQL大小写敏感配置 zoerywzhou@163.com http://www.cnblogs.com/swje/ 作者:Zhouwan 2017-3-27 最近在window ...