5 条题解
-
15
对于这个问题,我们需要将员工按照一定规则划分为若干个组,使得在每个组内没有直接上下级的关系。题目要求形成的组数最少,因此我们可以采用深度优先搜索(DFS)的方法来解决。
首先,我们可以用一个数组
f
来表示每个员工的直接上级。数组中第i
个元素的值f[i]
表示第i
个员工的直接上级编号。如果f[i]
的值为 -1,则表示第i
个员工没有直接上级,即是根节点。接下来,我们需要编写一个函数
dep(x, len)
来计算员工x
的深度,其中len
表示当前深度。如果员工x
没有直接上级(即f[x] == -1
),则返回len
作为最终深度;否则,递归调用dep(f[x], len + 1)
来计算其直接上级的深度,并加1表示当前员工的深度。为了找到形成的组数最少,我们需要遍历所有员工,对每个员工调用
dep
函数计算其深度,并更新最大深度值maxdep
。最后,输出maxdep
即为所求的答案。由于每个员工都需要调用
dep
函数计算深度,时间复杂度为O(n^2)
。对于较小的n
,这个复杂度是可以接受的。总结思路:
- 构建数组
f
表示每个员工的直接上级,其中f[i]
表示第i
个员工的直接上级编号。 - 编写函数
dep(x, len)
来计算员工x
的深度,其中len
表示当前深度。 - 遍历所有员工,对每个员工调用
dep
函数计算深度,并更新最大深度值maxdep
。 - 输出
maxdep
即为形成的最少组数。
PY:
def dep(x, f): if f[x] == -1: return 1 return dep(f[x], f) + 1 n = int(input()) f = [-1] * (n + 1) for i in range(1, n + 1): f[i] = int(input()) maxdep = 0 for i in range(1, n + 1): maxdep = max(maxdep, dep(i, f)) print(maxdep)
C++:
#include <iostream> #include <vector> using namespace std; int dep(int x, vector<int>& f) { if (f[x] == -1) { return 1; } return dep(f[x], f) + 1; } int main() { int n; cin >> n; vector<int> f(n + 1, -1); for (int i = 1; i <= n; i++) { cin >> f[i]; } int maxdep = 0; for (int i = 1; i <= n; i++) { maxdep = max(maxdep, dep(i, f)); } cout << maxdep << endl; return 0; }
- 构建数组
-
9
点击查收题解
题目描述
P1070. 聚会
一家公司有 n(1≤n≤2×103)(1≤n≤2×103) 名员工,从第 1** 人到第 n 人。每个员工要么没有直接经理,要么只有一个直接经理,后者是另一个具有不同编号的员工。如果以下情况中至少有一个是正确的,则称 A 雇员是 B 雇员的上级:
雇员 A 是雇员 B 的直接经理。
雇员 B 有一个直接经理雇员 C,雇员 A 是雇员 C 的上级。
公司不存在管理循环,也就是说,不存在一个员工是他/她自己的上级。
今天公司将安排一个聚会。这涉及到将所有 n 个雇员分为几个组:每个雇员必须恰好属于一个组。此外,在任何一个集团内,不得有两名雇员 A 和 B,满足 A 是 B 的上级。
必须组成的组的最小数目是多少?
输入格式
第一行包含整数 n ( 1≤n≤2000 ) — 员工人数。
接下来的 n 行包含整数 pi (1≤pi≤n 或pi=−1)。每个 pi 表示第 i 个员工的直接上级。如果pi = -1,则表示第 i 个员工没有直接上级。
保证不会出现管理循环。
输出格式
输出一个整数,表示聚会中将形成的最少组数。
思路
本题中各个职员间有所属关系,并且没有管理循环,依此我们可以建立一棵树,最上级为根节点,最下级为子节点,定义deep数组储存每个人的深度,注意p可能为-1,而下标却不能为-1,所以把-1号人设为第0号人,所以p要与0求较大值,此时遍历求最大深度即可得出AC答案
易错点
在此种思路下,把第0号人当作所有人的上级,即根节点。但实际上并不存在第0号人,所以第0号的深度初始设置是0,定义成全局变量则无需初始化
代码
#include <bits/stdc++.h> using namespace std; vector<int> v[5000]; int deep[5000]; int ans; void dfs(int x) { for (int i = 0;i < (int)v[x].size();i++) { deep[v[x][i]] = deep[x] + 1; ans = max(ans,deep[v[x][i]]); dfs(v[x][i]); } } int main() { int n,p; cin >> n; for (int i = 1;i <= n;i++) { cin >> p; v[max(p,0)].push_back(i); } dfs(0); cout << ans; return 0; }
累死了,只能问上一句,你点赞了吗?😵 V
100 Accepted
状态
分数
#1
10
#2
10
1ms
7.6 MiB
#3
10
0ms
#4
10
1ms
#5
10
1ms
#6
10
1ms
#7
v
10
1ms
#8
10
0ms
#9
10
0ms
7.6 MiB
7.5 MiB
7.4 MiB
7.4 MiB
7.8 MiB
7.6 MiB
7.5 MiB
#10
v Accepted
v Accepted
v Accepted
v Accepted
v Accepted
V Accepted
Accepted
v Accepted
v Accepted
v Accepted
耗时
1ms
内存占用
7.6 MiB
10
1ms
7.4 MiB
-
-9
话不多说,直接上主要代码。
vector<int> v[5000]; int deep[5000]; int ans; void dfs(int x) { for (int i = 0;i < (int)v[x].size();i++) { deep[v[x][i]] = deep[x] + 1; ans = max(ans,deep[v[x][i]]); dfs(v[x][i]); } } int main() { int n,p; cin >> n; for (int i = 1;i <= n;i++) { cin >> p; v[max(p,0)].push_back(i); } dfs(0); cout << ans;
你点赞了吗? 注:为你好,自己写头文件与返回值。
-
-11
AC代码
#include <bits/stdc++.h> using namespace std; int dep(int x, vector < int > & f){ if (f[x] == -1) { return 1; } return dep(f[x], f) + 1; } int main() { int n; cin >> n ; vector < int > f(n + 1, -1); for (int i = 1; i <= n ; i ++) { cin >> f[i]; } int maxx = 0; for (int i = 1; i <= n ; i ++) { maxx = max(maxx , dep(i, f)); } cout << maxx; }
- 1
信息
- ID
- 265
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 2
- 标签
- (无)
- 递交数
- 644
- 已通过
- 382
- 上传者