2020.08.07【NOIP提高组】模拟:树环转换 总结
Description
给定一棵
N
N
N个节点的树,去掉这棵树的一条边需要消耗值
1
1
1,为这个图的两个点加上一条边也需要消耗值
1
1
1。树的节点编号从
1
1
1开始。在这个问题中,你需要使用最小的消耗值(加边和删边操作)将这棵树转化为环,不允许有重边。
环的定义如下:
(1)该图有
N
N
N个点,
N
N
N条边。
(2)每个顶点的度数为
2
2
2。
(3)任意两点是可达的。
树的定义如下:
(1)该图有
N
N
N个点,
N
−
1
N-1
N−1条边。
(2)任意两点是可达的。
Input
第一行是一个整数
N
N
N,代表节点的个数。
接下来
N
−
1
N-1
N−1行,每行有两个整数
U
,
V
(
1
≤
U
,
V
≤
N
)
U,V(1\leq U,V\leq{N})
U,V(1≤U,V≤N),表示双向边
(
U
,
V
)
(U, V)
(U,V)。
Output
输出把树转化为环的最小消耗值。
Sample Input
4
1 2
2 3
2 4
Sample Output
3
Data Constraint
对于
20
%
20\%
20%的数据,有
1
≤
N
≤
10
1\leq N\leq10
1≤N≤10;
对于
100
%
100\%
100%的数据,有
1
≤
N
≤
1000000
1\leq N\leq1000000
1≤N≤1000000。
总结
比赛思路: 推了一下树形
d
p
dp
dp,发现不能,结果就没打。
正解: 是树形
d
p
dp
dp 。我们知道一条链上加一条边就得到了一个环,首先考虑链。设
f
i
,
0
f_{i,0}
fi,0表示以
i
i
i为根的子树最少花多少代价变成链,根结点
i
i
i在这个链的端点上(度数为
1
1
1),
f
i
,
1
f_{i,1}
fi,1表示同上,但是根结点
i
i
i在这个链中间(度数为
2
2
2)。并设
s
o
n
i
son_{i}
soni表示
i
i
i的儿子的集合,
s
i
s_i
si表示
i
i
i的儿子数量。则可以进行转移。
首先考虑
f
i
,
0
f_{i,0}
fi,0。
第一种情况如下:
另一种情况如下:
注:红色表示被割掉。
第一种情况的子树都在中间,所以答案为
(
∑
j
∈
s
o
n
i
f
j
,
1
)
+
2
×
s
i
\begin{aligned}(\sum_{j\in{son_i}}{f_{j,1}})+2\times s_i\end{aligned}
(j∈soni∑fj,1)+2×si。
第二种情况有一个结点在端点上,所以答案为
(
∑
j
∈
s
o
n
i
f
j
,
1
)
−
f
k
,
1
+
f
k
,
0
+
2
×
(
s
i
−
1
)
\begin{aligned}(\sum_{j\in{son_i}}{f_{j,1}})-f_{k,1}+f_{k,0}+2\times(s_i-1)\end{aligned}
(j∈soni∑fj,1)−fk,1+fk,0+2×(si−1)。
注:
k
k
k表示任意一个子结点。
其次是求
f
i
,
1
f_{i,1}
fi,1。
我们可以直接调用原来
f
i
,
0
f_{i,0}
fi,0的值,但是还有另一种情况:
这种情况下,答案为
(
∑
j
∈
s
o
n
i
f
j
,
1
)
−
f
p
,
1
−
f
q
,
1
+
f
p
,
0
+
f
q
,
0
+
2
×
(
s
i
−
2
)
\begin{aligned}(\sum_{j\in{son_i}}{f_{j,1}})-f_{p,1}-f_{q,1}+f_{p,0}+f_{q,0}+2\times(s_i-2)\end{aligned}
(j∈soni∑fj,1)−fp,1−fq,1+fp,0+fq,0+2×(si−2)。
我们发现,上述答案要求最小,所以
u
,
p
,
q
u,p,q
u,p,q这
3
3
3个未知数要维护最大。每一次不用暴力维护,只用两个变量即可。
注:本题
d
f
s
dfs
dfs会爆栈,需要手写栈或者用
b
f
s
bfs
bfs。
时间复杂度为
O
(
n
)
O(n)
O(n)。