0%

2026 杭电暑期多校 8-1008-分数越小还是越大越好

题目大意

分数越小还是越大越好

给定一棵包含 NN 个顶点的树,顶点编号为 1,2,…,N1,2,\ldots,N。

你需要选择一个 00 到 N−1N-1 的排列 PP,并将 PiP_i 作为顶点 ii 的标签。

对于一个整数集合 SS,定义 MEX⁡(S)\operatorname{MEX}(S) 为没有出现在 SS 中的最小非负整数。

对于两个顶点 u,vu,v,设它们之间简单路径上的顶点集合为 V(u,v)V(u,v)(当 u=vu=v 时 V(u,v)={u}V(u,v)=\{u\}),定义

f(u,v)=MEX⁡({Px∣x∈V(u,v)}).f(u,v)=\operatorname{MEX}\bigl(\{P_x \mid x\in V(u,v)\}\bigr).

树的分数定义为

score⁡(P)=∑u=1N∑v=uNf(u,v).\operatorname{score}(P)=\sum_{u=1}^{N}\sum_{v=u}^{N} f(u,v).

求在所有标签排列 PP 中,树的最小可能分数与最大可能分数。

第一行一个整数 TT,表示测试数据组数。

每组测试数据格式如下:

  • 第一行一个整数 NN,表示树的顶点数;

  • 接下来 N−1N-1 行,每行两个整数 u,vu,v,表示树中存在一条连接顶点 uu 与顶点 vv 的无向边。

数据范围:

  • 3≤N≤20003\le N\le 2000;

  • 1≤u,v≤N1\le u,v\le N;

  • 保证给出的边构成一棵树。

OJ 中只有一个正式测试点,该测试点满足:

  • T=1000T=1000;

  • ∑N2=2×107\sum N^2=2\times 10^{7}。

对于每组测试数据输出一行两个整数,分别表示树的最小可能分数与最大可能分数。

1
2
3
4
5
6
7
8
9
10
11
12
13
3
3
1 2
2 3
4
1 2
1 3
1 4
5
1 2
1 3
1 4
1 5
1
2
3
5 7
5 11
6 16

第一组数据:树是一条链 1−2−31-2-3,需要把 {0,1,2}\{0,1,2\} 分配给三个顶点。

取 P=(0,2,1)P=(0,2,1),即 P1=0,  P2=2,  P3=1P_1=0,\;P_2=2,\;P_3=1:

(u,v)(u,v) 路径上的标签集合 f(u,v)f(u,v)
(1,1)(1,1) {0}\{0\} 11
(1,2)(1,2) {0,2}\{0,2\} 11
(1,3)(1,3) {0,2,1}\{0,2,1\} 33
(2,2)(2,2) {2}\{2\} 00
(2,3)(2,3) {2,1}\{2,1\} 00
(3,3)(3,3) {1}\{1\} 00

总和为 55,这是该树能取到的最小分数。

取 P=(1,0,2)P=(1,0,2):

(u,v)(u,v) 路径上的标签集合 f(u,v)f(u,v)
(1,1)(1,1) {1}\{1\} 00
(1,2)(1,2) {1,0}\{1,0\} 22
(1,3)(1,3) {1,0,2}\{1,0,2\} 33
(2,2)(2,2) {0}\{0\} 11
(2,3)(2,3) {0,2}\{0,2\} 11
(3,3)(3,3) {2}\{2\} 00

总和为 77,这是该树能取到的最大分数。

第二组数据:树是以顶点 11 为中心、含 33 片叶子的菊花图,枚举全部 4!=244!=24 种标签排列可知分数的取值范围为 [5,11][5,11]。

第三组数据:树是以顶点 11 为中心、含 44 片叶子的菊花图,枚举全部 5!=1205!=120 种标签排列可知分数的取值范围为 [6,16][6,16]。

思路讲解

最小化的情况比较简单:

是链的话,那么就是 2∗N−12*N-1。

image

不是链的话就是 N+1 啊。

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cin >> N;
vector<vector<int> > g(N + 2);
for (int i = 1; i <= N - 1; ++i) {
ll u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
ll leaf_ct = 0;
for (int i = 1; i <= N; ++i) {
if (SZ(g[i]) == 1) {
leaf_ct++;
}
}
if (leaf_ct <= 2) {
// 一条链的情况
cout << 2 * N - 1 << " ";
} else {
cout << N + 1 << " ";
}

求解最大值

状态定义
设 DP(u,v)DP(u, v) 表示:将标签 0,1,…,dist⁡(u,v)0, 1, \dots, \operatorname{dist}(u, v) 分配给路径 u…vu \dots v 上的所有节点,所能获得的最大累计贡献分数。

那么这个DP状态是如何定义出来的?我们在近期训练题目一句话总结里面写了。

image

image

image

AC代码

心路历程(WA,TLE,MLE……)