[Usaco2010 Hol]cowpol 奶牛政坛

题目大意

数据范围:如题面。


题解

第一想法是一个复杂度踩标程的算法.....

就是每种政党建一棵虚树,然后对于每棵虚树都暴力求直径就好了,复杂度是$O(n)$的。

想想就巨难写好么.....

思考这样的问题:我们求直径的第一种方法是任选一个点,然后暴力跑最长链对吧。那么我们不妨设任选这个点是根节点,那么此时的最长链就是不同正当中$dep$最大的一个是吧。

也就是说,我们已经知道了,每个政党的直径的一个端点。

接下来我们就枚举每个点,暴力求它到已知同政党端点的距离,这个用倍增$lca$来求就好。

复杂度$O(nlogn)$。

代码

#include <bits/stdc++.h>

#define N 200010 

using namespace std;

int to[N << 1], nxt[N << 1], head[N], tot;

int f[20][N], dep[N], id[N], a[N], p[N], ans[N];

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

int rd() {
int x = 0, f = 1;
char c = nc();
while (c < 48) {
if (c == '-')
f = -1;
c = nc();
}
while (c > 47) {
x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
}
return x * f;
} inline void add(int x, int y) {
to[ ++ tot] = y;
nxt[tot] = head[x];
head[x] = tot;
} void dfs(int p, int fa) {
f[0][p] = fa;
for (int i = 1; i <= 19; i ++ ) {
f[i][p] = f[i-1][f[i-1][p]];
}
dep[p] = dep[fa] + 1;
for (int i = head[p]; i; i = nxt[i]) {
if (to[i] != fa) {
dfs(to[i], p);
}
}
} int lca(int x, int y) {
if (dep[x] < dep[y]) {
swap(x, y);
}
for (int i = 19; ~i; i -- ) {
if (dep[f[i][x]] >= dep[y]) {
x = f[i][x];
}
}
if (x == y) {
return x;
}
for (int i = 19; ~i; i -- ) {
if (f[i][x] != f[i][y]) {
x = f[i][x];
y = f[i][y];
}
}
return f[0][x];
} int main() {
int n = rd(), k = rd();
for (int i = 1; i <= n; i ++ ) {
a[i] = rd(), p[i] = rd();
if (p[i]) {
add(p[i], i);
add(i, p[i]);
}
} dfs(1, 1); for (int i = 1; i <= n; i ++ ) {
if(dep[id[a[i]]] < dep[i]) {
id[a[i]] = i;
}
} for (int i = 1; i <= n; i ++ ) {
ans[a[i]] = max(ans[a[i]], dep[id[a[i]]] + dep[i] - 2*dep[lca(id[a[i]], i)]);
} for (int i = 1; i <= k; i ++ ) {
printf("%d\n", ans[i]);
}
return 0;
}

小结:思考问题一定要相处最简单的方法加以实践。

[bzoj1776][Usaco2010 Hol]cowpol 奶牛政坛_倍增lca的更多相关文章

  1. [BZOJ1776][Usaco2010 Hol]cowpol 奶牛政坛

    Description 农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N.恰好有N-1条单位长度的双向道路,用各种各样的方法连接这些草地.而且从每片 ...

  2. 【BZOJ1776】[Usaco2010 Hol]cowpol 奶牛政坛 树的直径

    [BZOJ1776][Usaco2010 Hol]cowpol 奶牛政坛 Description 农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N. ...

  3. COGS——T 803. [USACO Hol10] 政党 || 1776: [Usaco2010 Hol]cowpol 奶牛政坛

    http://www.lydsy.com/JudgeOnline/problem.php?id=1776||http://cogs.pro/cogs/problem/problem.php?pid=8 ...

  4. [Usaco2010 Hol]cowpol 奶牛政坛

    题目描述: 农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N.恰好有N-1条单位长度的双向道路,用各种各样的方法连接这些草地.而且从每片草地出发都可 ...

  5. bzoj:1776: [Usaco2010 Hol]cowpol 奶牛政坛

    Description 农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N.恰好有N-1条单位长度的双向道路,用各种各样的方法连接这些草地.而且从每片 ...

  6. bzoj 1776: [Usaco2010 Hol]cowpol 奶牛政坛——树的直径

    农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N.恰好有N-1条单位长度的双向道路,用各种各样的方法连接这些草地.而且从每片草地出发都可以抵达其他所 ...

  7. 【BZOJ】1776: [Usaco2010 Hol]cowpol 奶牛政坛

    [题意]给定n个点的树,每个点属于一个分类,求每个分类中(至少有2个点)最远的两点距离.n<=200000 [算法]LCA [题解]结论:树上任意点集中最远的两点一定包含点集中深度最大的点(求树 ...

  8. bzoj [Usaco2010 Hol]cowpol 奶牛政坛【树链剖分】

    意识流虚树 首先考虑只有一个党派,那么可以O(n)求树的直径,步骤是随便指定一个根然后找距离根最远点,然后再找距离这个最远点最远的点,那么最远点和距离这个最远点最远的点之间的距离就是直径 那么考虑多党 ...

  9. BZOJ 1776: [Usaco2010 Hol]cowpol 奶牛政坛 LCA + 树的直径

    Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) ...

随机推荐

  1. list深拷贝和浅拷贝

    在Python中,经常要对一个list进行复制.对于复制,自然的就有深拷贝与浅拷贝问题.深拷贝与浅拷贝的区别在于,当从原本的list复制出的list之后,修改其中的任意一个是否会对另一个造成影响,即这 ...

  2. no suitable method found to override

    no suitable method found to override http://bbs.csdn.net/topics/200001058 

  3. Poj 3764 The xor-longest Path(Trie树+xor+贪心)

    The xor-longest Path Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6455 Accepted: 1392 ...

  4. Cogs 734. [网络流24题] 方格取数问题(最大闭合子图)

    [网络流24题] 方格取数问题 ★★☆ 输入文件:grid.in 输出文件:grid.out 简单对比 时间限制:1 s 内存限制:128 MB «问题描述: 在一个有m*n 个方格的棋盘中,每个方格 ...

  5. NVMe Windows 支持情况

    From NVMe 官网: Windows Driver – Microsoft Inbox • Closed source driver (Microsoft)• Inbox driver to W ...

  6. ros中同时订阅两个topic(2张图像)合并成一个topic(1张图像)

    2019-12-06 15:42:39 先暂时做个资料保存 要同时用两个红外相机,但是没有做硬件上的 时间戳同步,就是笔记本上同时插着两个相机. 两个topic发布各自相机的图像,然后要有个节点同时订 ...

  7. c 判断一个字符是否为字母数字

    #include <stdio.h> #include <wctype.h> int main () { int i; wchar_t str[] = L"c3po. ...

  8. Java基础_死锁、线程组、定时器Timer

    一.死锁问题: 死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放.由于线程被无限期地阻塞,因此程序不可能正常终止. 比如,线程一需要第一把所,此时锁处于空闲状态,给了 ...

  9. async for 在爬虫中的使用例子

    import asyncio import re import typing from concurrent.futures import Executor, ThreadPoolExecutor f ...

  10. ORA-12899 导入失败

    主要是目标数据库的字符集与导入文件的字符集不符 SQL>SHUTDOWN IMMEDIATE SQL>STARTUP MOUNT SQL>ALTER SYSTEM ENABLE RE ...