Codeforces #115 A 树+最大层数

公司员工分为无上级和有上级两类,组织聚会时要求同一组内不存在上下级关系。给定每个员工的直接上级,求最少需要分成多少个组。输入包括员工数量及每个员工的直接上级,保证无循环管理。通过构建树形结构,自底向上计算最大深度,输出结果。

   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.


input
5
-1
1
2
1
-1

output
3

题目大意:

输入n个员工,编号从1到n。接着是n行,分别为这n个员工的直系经理的编号,如果为-1,则说明此员工没有直系经理。

用树的图形来解此题,求树的最高层数。因为我们输入的是每个成员的上司编号,即父节点的编号,所以只需从叶子节点开始向上搜,求出最大的层数即可。


代码实现:

#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<cmath>
#include<algorithm>
#include<string>
#include<string.h>
using namespace std;

int father[2010];

int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        for (int i = 1; i <= n; i++)
            scanf("%d", &father[i]);      //输入经理的编号
        int ans;
        int cnt = 0;
        for (int i = 1; i <= n; i++) {
            ans = 0;                    //记录树的深度
            for (int j = i; j <= n; j = father[j]) {   //j=father[j]用于判断是否已到根节点,如果到了根节
                                                                 //点,则循环结束,此时的ans就是深度。
                if (j != -1)
                    ans++;
                else
                    break;
            }
            cnt = max(cnt, ans);          //更新数据,找到最大的那个值即是答案
        }
        printf("%d\n", cnt);
    }
    return 0;
}

 




### Codeforces Round 703 Div. 2 比赛题解与总结 #### A. Adjacent Replacements Problem 对于此问题,给定一个长度为 \(n\) 的整数数组 \(a_1, a_2, \ldots , a_n\) 和一个正整数 \(k\). 如果存在一对相邻位置 \(i,i+1\) (\(1≤i<n\)),使得 \(|a_i−a_{i+1}|>k\) 则可以执行一次操作:选择任意一对这样的相邻元素并使它们相等。目标是最少的操作次数让所有的差值不超过 \(k\)[^1]。 解决方法是遍历整个数组,计算每对相邻元素之间的差异,并判断这些差异是否超过了 \(k\) 。如果超过,则记录下需要调整的位置数量作为最终的结果返回。 ```cpp #include <iostream> using namespace std; void solveA(){ int t; cin >> t; while(t--){ int n,k; cin>>n>>k; vector<int>a(n); for(auto& x:a){ cin>>x; } bool flag=true; int cnt=0; for(int i=0;i<n-1;++i){ if(abs(a[i]-a[i+1])>k){ ++cnt; flag=false; } } cout<<(flag?"Yes":"No")<<endl; } } ``` #### B. Minimum Grid Path 该题目要求在一个无限大小的网格上找到一条从起点到终点的最短路径,在移动过程中某些格子可能被标记为障碍物不可通过。为了最小化步数,应当优先考虑横向或纵向直线前进直到遇到阻碍为止;之后转向其他方向继续前行直至抵达目的地[^2]。 实现思路在于模拟行走过程中的决策逻辑——当面临多个可行的选择时总是挑选能够最快接近目标的那个选项。具体做法可以通过广度优先搜索算法来完成。 ```cpp // 假设此处省略了完整的B题解答代码... ``` #### C. Maximum width of Binary Tree 这个问题涉及到二叉的最大宽度定义以及如何有效地求得这一数值。最大宽度是指某一层拥有最多的节点数目。一种有效的策略是从根部开始逐层遍历整棵结构,利用队列辅助存储每一级待访问结点的信息,从而轻松统计各层的实际规模并找出其中最大的那个层次所含有的节点总数即为我们所需的答案[^3]。 上述三种不同类型的挑战展示了编程竞赛中常见的几种思考模式和技术手段的应用实例。无论是简单的贪心法还是较为复杂的图论模型构建都体现了选手们灵活运用基础知识解决问题的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值