Description

农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N。恰好有N-1条单位长度的双向道路,用各种各样的方法连接这些草地。而且从每片草地出发都可以抵达其他所有草地。也就是说,这些草地和道路构成了一种叫做树的图。输入包含一个详细的草地的集合,详细说明了每个草地的父节点P_i (0 <= P_i <= N)。根节点的P_i == 0, 表示它没有父节点。因为奶牛建立了1到K一共K (1 <= K <= N/2)个政党。每只奶牛都要加入某一个政党,其中, 第i只奶牛属于第A_i (1 <= A_i <= K)个政党。而且每个政党至少有两只奶牛。 这些政党互相吵闹争。每个政党都想知道自己的“范围”有多大。其中,定义一个政党的范围是这个政党离得最远的两只奶牛(沿着双向道路行走)的距离。 比如说,记为政党1包含奶牛1,3和6,政党2包含奶牛2,4和5。这些草地的连接方式如下图所 示(政党1由-n-表示):  政党1最大的两只奶牛的距离是3(也就是奶牛3和奶牛6的距离)。政党2最大的两只奶牛的距离是2(也就是奶牛2和4,4和5,还有5和2之间的距离)。 帮助奶牛们求出每个政党的范围。

Input

* 第一行: 两个由空格隔开的整数: N 和 K * 第2到第N+1行: 第i+1行包含两个由空格隔开的整数: A_i和P_i

Output

* 第1到第K行: 第i行包含一个单独的整数,表示第i个政党的范围。

Sample Input

6 2
1 3
2 1
1 0
2 1
2 1
1 5

Sample Output

3
2

Solution

其实就是树的距离。就是那个两遍$bfs$的东西

对每个政党都做一遍树的距离就好了

找一个深度最大的点,然后与同政党的所有点分别求一下$lca$,取个$max$

这样复杂度是$O(nlogn)$的(每个节点只会访问一次,$lca$效率$O(logn)$)

至于$lca$求法就随意了,这里写的是树剖

#include <bits/stdc++.h>

using namespace std ;

#define N 400010

int n , k , head[ N ] , cnt , s ;
int a[ N ] , fa[ N ] ;
int dep[ N ] , siz[ N ] , top[ N ] ;
int mx[ N ] ;
struct node {
int to , nxt ;
} e[ N ] ;
vector < int > vt[ N ] ; void ins( int u , int v ) {
e[ ++ cnt ].to = v ;
e[ cnt ].nxt = head[ u ] ;
head[ u ] = cnt ;
} void dfs1( int u ) {
siz[ u ] = ;
for( int i = head[ u ] ; i ; i = e[ i ].nxt ) {
if( e[ i ].to == fa[ u ] ) continue ;
dep[ e[ i ].to ] = dep[ u ] + ;
dfs1( e[ i ].to ) ;
siz[ u ] += siz[ e[ i ].to ] ;
}
} void dfs2( int u , int topf ) {
top[ u ] = topf ;
int k = ;
for( int i = head[ u ] ; i ; i = e[ i ].nxt ) {
if( e[ i ].to == fa[ u ] ) continue ;
if( siz[ e[ i ].to ] > siz[ k ] ) k = e[ i ].to ;
}
if( !k ) return ;
dfs2( k , topf ) ;
for( int i = head[ u ] ; i ; i = e[ i ].nxt ) {
if( e[ i ].to == k || e[ i ].to == fa[ u ] ) continue ;
dfs2( e[ i ].to , e[ i ].to ) ;
}
} int lca( int x , int y ) {
while( top[ x ] != top[ y ] ) {
if( dep[ top[ x ] ] < dep[ top[ y ] ] ) swap( x , y ) ;
x = fa[ top[ x ] ] ;
}
if( dep[ x ] > dep[ y ] ) swap( x , y ) ;
return x ;
} bool cmp( int a , int b ) {
return dep[ a ] > dep[ b ] ;
} int main() {
scanf( "%d%d" , &n , &k ) ;
for( int i = ; i <= n ; i ++ ) {
int p ;
scanf( "%d%d" , &a[ i ] , &p ) ;
fa[ i ] = p ;
if( p ) ins( i , p ) , ins( p , i ) ;
vt[ a[ i ] ].push_back( i ) ;
if( p == ) s = i ;
}
dfs1( s ) ;
dfs2( s , s ) ;
for( int i = ; i <= k ; i ++ ) {
int ans = ;
sort( vt[ i ].begin() , vt[ i ].end() , cmp ) ;
for( int j = , len = vt[ i ].size() ; j < len ; j ++ ) {
int l = lca( vt[ i ][ ] , vt[ i ][ j ] ) ;
ans = max( ans , dep[ vt[ i ][ ] ] + dep[ vt[ i ][ j ] ] - * dep[ l ] ) ;
}
printf( "%d\n" , ans ) ;
}
return ;
}

[BZOJ1776][Usaco2010 Hol]cowpol 奶牛政坛的更多相关文章

  1. [bzoj1776][Usaco2010 Hol]cowpol 奶牛政坛_倍增lca

    [Usaco2010 Hol]cowpol 奶牛政坛 题目大意: 数据范围:如题面. 题解: 第一想法是一个复杂度踩标程的算法..... 就是每种政党建一棵虚树,然后对于每棵虚树都暴力求直径就好了,复 ...

  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. bzoj:1776: [Usaco2010 Hol]cowpol 奶牛政坛

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

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

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

  6. [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. easyUi引入方法

    1:创建一个动态web工程:    去官网http://www.jeasyui.net/download/下载官网文档    我去官网下载的最新版本,个人根据自己的需求下载即可.2:在webConte ...

  2. 【代码备份】ZJ10086测试环境成功代码备份

    vuser_init(){        lr_start_transaction("login"); web_url("101.132.17.138",   ...

  3. UIPageViewController基本使用

    UIPageViewController基本使用 @interface ViewController ()<UIPageViewControllerDelegate,UIPageViewCont ...

  4. [django]form不清空问题解决

    https://www.cnblogs.com/OldJack/p/7118396.html 有时候提交表单后,发现某个字段写错了,但是form的其他字段竟然被清空,这个万万不能接受.所有django ...

  5. Choose the best route(迪杰斯特拉)

    通过做这题,发现了自己的问题很大,做题不是贴代码,而是要了解思想:这题考的是有一个起点的集合,求起点集合到一个终点的最短距离, 本来想用Floy的但一看map[1000][1000]超时,有向图,逆序 ...

  6. session超时时间设置

    在Tomcat的web.xml文件中修改如下标签 <session-config> <session-timeout>10</session-timeout> &l ...

  7. numpy.random.rand()/randn()/randint()/normal()/choice()/RandomState()

    这玩意用了很多次,但每次用还是容易混淆,今天来总结mark一下~~~ 1. numpy.random.rand(d0,d1,...,dn) 生成一个[0,1)之间的随机数或N维数组 np.random ...

  8. 持续集成之三:搭建Maven私服Nexus

    安装环境 Red Hat Enterprise Linux Server release 7.3 (Maipo) jdk1.7.0_80 apache-tomcat-7.0.90 mysql-5.7. ...

  9. Hive 体系结构介绍

    下面是Hive的架构图. 图1.1 Hive体系结构 Hive的体系结构可以分为以下几部分: (1)用户接口主要有三个:CLI,Client 和 WUI.其中最常用的是CLI,Cli启动的时候,会同时 ...

  10. linux常用命令:tr 命令

    tr 命令实现字符转换功能,其功能类似于 sed 命令,但是,tr 命令比 sed 命令简单.也就是说,tr 命令能实现的功能,sed 命令都可以实现.尽管如此,tr 命令依然是 Linux 系统下处 ...