Problem Description
You are given a rooted tree consisting of nn vertices numbered from 11 to nn, and the root is vertex 11.
Vertex ii has a natural number weight a_iai, and \textbf{no two different vertexes have the same weight}no two different vertexes have the same weight.
Define b_u = MEXbu=MEX { x \space | \space \exists v \in subtree\left( u \right), x = a_vx ∣ ∃v∈subtree(u),x=av}.
Unfortunately, a_iai are not given. Please find out the maximum possible \sum_{i=1}^{n}b_i∑i=1nbi.
The \textbf{MEX}MEX of a set is the minimum non-negative integer that doesn't belong to the set.
Input
The first line contains one integer T \left( 1 \leq T \leq 10 \right)T(1≤T≤10), indicating the number of test cases.
For each test case:
The first line contains one integer n \left( 1 \le n \le 5 \cdot 10^5 \right)n(1≤n≤5⋅105), indicating the number of nodes.
In the following n-1n−1 lines, each line contains two interger u, v \left(1 \le u, v \le n \right)u,v(1≤u,v≤n), indicating an edge \left( u, v \right)(u,v) of the tree.
A guarantee is that forming trees.
Output
For each test case: One line with an integer, indicating the maximum possible \sum_{i=1}^{n}b_i∑i=1nbi.
Sample Input
3
5
1 2
3 2
1 5
4 1
3
1 2
2 3
1
Sample Output
8
6
1
题意: 给出一棵树,树上各点都有一个点权ai,还各有一个价值bi,bi的值是点i子树中a值集合的MEX,ai的值可以为任意自然数,并且各ai值不同,求bi加和的最大值。
分析: 根据样例模拟一下可知,只有从根节点到某个叶子结点路径上的点才会对答案有贡献,而且这个贡献值一定是该点子树中点的个数,可以设状态dp[i]表示在以i为根的子树中得到的b加和最大值,显然初始状态也就是叶子结点的dp值为1,之后当前结点now的dp值可以由子结点dp值加上子树中点个数得到,显然我们应该选取dp值最大的那个子结点,最后答案就是dp[1]。
具体代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#define int long long
using namespace std;
vector<int> tr[500005];
int num[500005], dp[500005];
void dfs(int now, int fa){
int mx = 0;
for(int i = 0; i < tr[now].size(); i++){
int to = tr[now][i];
if(to == fa) continue;
dfs(to, now);
num[now] += num[to]+1;
mx = max(mx, dp[to]);
}
dp[now] = mx+num[now]+1;
}
signed main()
{
int T;
cin >> T;
while(T--){
int n;
scanf("%lld", &n);
for(int i = 1; i <= n; i++){
dp[i] = 0;
num[i] = 0;
tr[i].clear();
}
for(int i = 1; i < n; i++){
int u, v;
scanf("%lld%lld", &u, &v);
tr[u].push_back(v);
tr[v].push_back(u);
}
dfs(1, 0);
printf("%lld\n", dp[1]);
}
return 0;
}