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. Python 类和对象-下

    类的常用函数 #issubclass() 检测一个类是否是另外一个或者一组类中的子类 class Father: pass class Mother: pass class LaoWang: pass ...

  2. arc073 F many moves(dp + 线段树)

    设dp[i][y]表示一个点在x[i],另一个点在y时最小要走的步数 那么有以下转移 对于y != x[i-1]的状态,可以证明,他们直接加|x[i] - x[i-1]|即可(如果有其他方案,不符合对 ...

  3. [WC2007]剪刀石头布——费用流

    比较有思维含量的一道题 题意:给混合完全图定向(定向为竞赛图)使得有最多的三元环 三元环条件要求比较高,还不容易分开处理. 正难则反 考虑,什么情况下,三元组不是三元环 一定是一个点有2个入度,一个点 ...

  4. 十个迅速提升JQuery性能的技巧

    本文提供即刻提升你的脚本性能的十个步骤.不用担心,这并不是什么高深的技巧.人人皆可运用!这些技巧包括: 使用最新版本 合并.最小化脚本 用for替代each 用ID替代class选择器 给选择器指定前 ...

  5. Unescape JavaScript's escape() using C#

    js里面的 unescape escape 对应C#里面 var unescapedString = Microsoft.JScript.GlobalObject.unescape(yourEscap ...

  6. async的用法

    package com.example.administrator.myapplication; import android.os.AsyncTask; import android.util.Lo ...

  7. jquery的ajax实现方式

    在JQuery中,AJAX有三种实现方式:$.ajax() , $.post , $.get(). 首先我们看$.get(): .代码如下: $.get("test.jsp", { ...

  8. Idea切换svn分支,类似Eclipse的Switch功能

    vcs --> subversion --> update directory --> 勾选中 Update/Switch to specific url 重新设置新的URL即可

  9. 【EOJ3652】乘法还原(二分图)

    题意: 思路:Orz Claris 先找出所有平方项,将与有平方项的数有关的数对暂时忽略,剩下的直接连边就是一张二分图,暴力DFS染色 将有平方项的数两边都加一个,再判字典序即可 我不会判字典序……耽 ...

  10. react框架

    react 其实react=vue, 区别:vue-  双向数据绑定, react  单向数据绑定. 中文文档:https://react.docschina.org/ 第一步:安装方式,不能直接引入 ...