CF

A. Party

time limit per test3 seconds

memory limit per test256 megabytes

inputstandard input

outputstandard output

A company has n employees numbered from 1 to n. Each employee either has no immediate manager or exactly one immediate manager, who is another employee with a different number. An employee A is said to be the superior of another employee B if at least one of the following is true:

Employee A is the immediate manager of employee B

Employee B has an immediate manager employee C such that employee A is the superior of employee C.

The company will not have a managerial cycle. That is, there will not exist an employee who is the superior of his/her own immediate manager.

Today the company is going to arrange a party. This involves dividing all n employees into several groups: every employee must belong to exactly one group. Furthermore, within any single group, there must not be two employees A and B such that A is the superior of B.

What is the minimum number of groups that must be formed?

Input

The first line contains integer n (1 ≤ n ≤ 2000) — the number of employees.

The next n lines contain the integers pi (1 ≤ pi ≤ n or pi = -1). Every pi denotes the immediate manager for the i-th employee. If pi is -1, that means that the i-th employee does not have an immediate manager.

It is guaranteed, that no employee will be the immediate manager of him/herself (pi ≠ i). Also, there will be no managerial cycles.

Output

Print a single integer denoting the minimum number of groups that will be formed in the party.

Examples

inputCopy

5

-1

1

2

1

-1

outputCopy

3

Note

For the first example, three groups are sufficient, for example:

Employee 1

Employees 2 and 4

Employees 3 and 5

【分析】:若是并查集,不要路径压缩,因为要记录深度。输出最大深度即可。

[DFS]

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e5 + 10;
const int mod = 142857;
const int inf = 0x3f3f3f3f; int n,vis[maxn],cnt,x,ans;
vector<int> G[maxn]; void dfs(int root, int cur)
{
ans=max(ans,cur);
for(int i=0;i<G[root].size();i++)
{
vis[G[root][i]]=1;
dfs(G[root][i],cur+1);
}
} int main()
{
while(~scanf("%d",&n))
{
memset(vis,0,sizeof(vis));
for(int i=0;i<=n;i++) G[i].clear();
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
if(x!=-1) G[x].push_back(i);
}
ans=0;
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
vis[i]=1;
dfs(i,1);
}
}
printf("%d\n",ans);
}
}
#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e5 + 10;
const int mod = 142857;
const int inf = 0x3f3f3f3f; int n,fa[maxn],cnt,x,ans;
vector<int> G[maxn]; void dfs(int i)
{
if(i==-1) return;
else
{
x++;
dfs(fa[i]);
}
} int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
{
scanf("%d",&fa[i]);
}
ans=0;
for(int i=1;i<=n;i++)
{
x=0;
dfs(i);
ans=max(ans,x);
}
printf("%d\n",ans);
}
}

[并查集]

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e5 + 10;
const int mod = 142857;
const int inf = 0x3f3f3f3f; int n,fa[maxn],cnt,x,ans;
vector<int> G[maxn]; void init(int n)
{
for(int i=1;i<=n;i++)
fa[i]=i;
}
void Find(int x)
{
if(x==fa[x])
return ;
cnt++;
Find(fa[x]);
} void join(int x,int y)
{
fa[x]=y;
return;
} int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
if(x!=-1)
join(i,x);
}
ans=0;
for(int i=1;i<=n;i++)
{
cnt=0;
Find(i);
ans=max(ans,cnt);
}
printf("%d\n",ans);
}
}

CF 115 A 【求树最大深度/DFS/并查集】的更多相关文章

  1. 求树的直径+并查集(bfs,dfs都可以)hdu4514

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 这题主要是叫我们求出树的直径,在求树的直径之前要先判断一下有没有环 树的直径指的就是一棵树上面距 ...

  2. 【bzoj2870】最长道路tree 树的直径+并查集

    题目描述 给定一棵N个点的树,求树上一条链使得链的长度乘链上所有点中的最小权值所得的积最大. 其中链长度定义为链上点的个数. 输入 第一行N 第二行N个数分别表示1~N的点权v[i] 接下来N-1行每 ...

  3. 【CF938G】Shortest Path Queries(线段树分治,并查集,线性基)

    [CF938G]Shortest Path Queries(线段树分治,并查集,线性基) 题面 CF 洛谷 题解 吼题啊. 对于每个边,我们用一个\(map\)维护它出现的时间, 发现询问单点,边的出 ...

  4. [BZOJ3038]上帝造题的七分钟2 树状数组+并查集

    考试的时候用了两个树状数组去优化,暴力修改,树状数组维护修改后区间差值还有最终求和,最后骗了40分.. 这道题有好多种做法,求和好说,最主要的是开方.这道题过的关键就是掌握一点:在数据范围内,最多开方 ...

  5. hdu 5458 Stability(树链剖分+并查集)

    Stability Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)Total ...

  6. 【BZOJ4025】二分图(线段树分治,并查集)

    [BZOJ4025]二分图(线段树分治,并查集) 题面 BZOJ 题解 是一个二分图,等价于不存在奇环. 那么直接线段树分治,用并查集维护到达根节点的距离,只计算就好了. #include<io ...

  7. 【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT

    题目描述 给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. $n\le 3\times 10^5$ ,$ ...

  8. cf1278D——树的性质+并查集+线段树/DFS判环

    昨天晚上本来想认真打一场的,,结果陪女朋友去了.. 回来之后看了看D,感觉有点思路,结果一直到现在才做出来 首先对所有线段按左端点排序,然后用并查集判所有边是否联通,即遍历每条边i,和前一条不覆盖它的 ...

  9. 51nod1307(暴力树剖/二分&dfs/并查集)

    题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1307 题意: 中文题诶~ 思路: 解法1:暴力树剖 用一个数 ...

随机推荐

  1. 【NOIP2017 D1 T1 小凯的疑惑】

    题目描述 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每种金币小凯都有 无数个.在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付的.现在小 凯想知道在无法准确支付的物品中,最贵的 ...

  2. 【BZOJ 1146】[CTSC2008]网络管理Network

    树剖+树状数组套线段树O(nlogn^3)(我打的),有一种更加优秀的算法是O(nlogn^2)的就是直接树状数组套线段树欧拉序(并不快),或者是用主席树维护原始的树的信息,同时用树状数组套线段树维护 ...

  3. vue-transition-fade

    <!Doctype> <html> <head> <meta charset="utf-8"> <meta name=&quo ...

  4. JavaScript获取HTML元素样式的方法(style、currentStyle、getComputedStyle)

    一.style.currentStyle.getComputedStyle的区别 style只能获取元素的内联样式,内部样式和外部样式使用style是获取不到的. currentStyle可以弥补st ...

  5. es6+最佳入门实践(13)

    13.模块化 13.1.什么是模块化 模块化是一种处理复杂系统分解为更好的可管理模块的方式.通俗的讲就是把一个复杂的功能拆分成多个小功能,并且以一种良好的机制管理起来,这样就可以认为是模块化.就像作家 ...

  6. es6+最佳入门实践(10)

    10.Generator 10.1.Generator是什么? Generator函数是ES6提供的一种异步编程解决方案.在它的内部封装了多个状态,因此,又可以理解为一种状态机,执行Generator ...

  7. centos 下构建lamp环境

    构建准备: 1.配置防火墙,开启80端口.3306端口 vi /etc/sysconfig/iptables -A INPUT -m state --state NEW -m tcp -p tcp - ...

  8. 利用os、hash模块生成目录下所有文件的md5

    hashlib用于对字符串或者文件进行加密. 使用方法1: hashlib.md5('str').hexdigest() 使用MD5对str进行加密,使用hexdigest(),16进制的方式打印   ...

  9. rtmp服务端实现

    前言 网上好像没一篇讲的很完善的,可能和公司保密有关吧.先就最让人困惑(至少我是这样)且网上也很少找到答案的一个点讲一下id各是什么意思? (如果我哪里理解错了,希望大神指出,毕竟我也是看了好多资料及 ...

  10. 【bzoj3289】mato的文件管理

    首先允许离线,一眼莫队…… 然后考虑对于每次移动,这不就是让你求逆序对嘛(QAQ) 考虑怎么移动? 每次在最后添加一个数,比这个数大的数都会与其形成一个逆序对 每次在最后移除一个数,比这个数大的数都会 ...