(公司聚会计划)一位公司主席正在向Stewart教授咨询公司聚会的计划。公司的内部结构关系是层次化的,即员工按“主管─下属”关系构成一颗树,根结点为公司主席。人事部按“宴会交际能力”为每个员工打分,分值为实数。为了使所有参加聚会的员工都感到愉快,主席不希望员工及其直接主管同时出席。
公司主席向Stewart教授提供公司结构树,采用10.4节介绍的左孩子右兄弟表示法描述。树中每个结点除了保存指针外,还保存员工的名字和宴会交际评分。设计算法,求宴会交际评分之和最大的宾客名单。分析算法的时间复杂度。
解
考虑一颗以
p
p
p为根的子树,
p
p
p的交际评分为
s
c
o
r
e
[
p
]
score[p]
score[p]。假设
p
p
p有
k
k
k个子结点,
p
c
1
,
p
c
2
,
…
,
p
c
k
p_{c1}, p_{c2}, … , p_{ck}
pc1,pc2,…,pck。根据
p
p
p是否参加聚会,分两种情况:①
p
p
p不参加聚会,假设此时以
p
p
p为根的子树的最大交际评分之和为
s
0
[
p
]
s_0[p]
s0[p];②
p
p
p参加聚会,假设此时以
p
p
p为根的子树的最大交际评分之和为
s
1
[
p
]
s_1[p]
s1[p]。下面建立
s
0
[
p
]
s_0[p]
s0[p]和
s
1
[
p
]
s_1[p]
s1[p]的递归式。
1)
p
p
p不参加聚会
在这种情况下,
p
p
p的任意一个子结点
p
c
i
p_{ci}
pci既可以选择参加聚会,也可以选择不参加聚会。如果
p
c
i
p_{ci}
pci不参加聚会,那么以
p
c
i
p_{ci}
pci为根的子树的交际评分之和为
s
0
[
p
c
i
]
s_0[p_{ci}]
s0[pci];如果
p
c
i
p_{ci}
pci参加聚会,那么以
p
c
i
p_{ci}
pci为根的子树的交际评分之和为
s
1
[
p
c
i
]
s_1[p_{ci}]
s1[pci]。二者中应当选取评分之和较大者。因此有
我们还需要记录在
p
p
p不参加聚会情况下,
p
p
p的每个子结点
p
c
1
,
p
c
2
,
…
,
p
c
k
p_{c1}, p_{c2}, … , p_{ck}
pc1,pc2,…,pck是否选择参加聚会。一般地,对任意一个结点
q
q
q,可以用一个变量
a
t
t
e
n
d
[
q
]
attend[q]
attend[q]来记录当
q
q
q的父结点不参加宴会时,
q
q
q是否要参加聚会。
a
t
t
e
n
d
[
q
]
attend[q]
attend[q]只取决于
s
0
[
q
]
s_0[q]
s0[q]和
s
1
[
q
]
s_1[q]
s1[q]的大小关系,如下所示。
2)
p
p
p参加聚会
在这种情况下,
p
p
p的所有儿子都不能参加聚会,因为
p
p
p的任意一个儿子不能与它的直接上司
p
p
p同时参加聚会。因此有
求解该问题时,我们可以从整个公司关系树的根结点开始,用递归的方式来计算树中所有结点的
s
0
[
p
]
s_0[p]
s0[p]、
s
1
[
p
]
s_1[p]
s1[p]和
a
t
t
e
n
d
[
p
]
attend[p]
attend[p]。
该算法对每个结点只会处理一次,而对每个结点的处理只需要常数时间,故算法的时间复杂度为
Θ
(
n
)
Θ(n)
Θ(n)。其中
n
n
n为公司的员工数。
本节相关的code后期再补上。
05-31
1628
07-01
4569