当前位置:网站首页>2022杭电多校六 1006-Maex (树形DP)
2022杭电多校六 1006-Maex (树形DP)
2022-08-05 05:42:00 【AC__dream】
题目链接:https://vjudge.net/contest/508623#problem/F
题目:
样例输入:
3
5
1 2
3 2
1 5
4 1
3
1 2
2 3
1样例输出:
8
6
1
题意:给你一个n个节点的有根树,根节点是1,我们可以给n个节点每个节点一个权值,但是任意两个节点的权值是不能相同的,定义bi为以第i个节点为根的子树中所有节点权值的mex值,的问我们
的最大值。
因为每个节点的权值必须两两不同,0只能在某个子树内,所以除了这个子树之外的其他节点所对应的b一定为0,所以我们可以尽可能让这棵子树之内的所有点的权值尽可能连续,那么我们根节点的b值就大。我们可以令f[i]表示以i节点为根的子树中所有节点的mex之和最大值是多少,再用一个cnt[i]记录以i节点为根的子树中所有节点的个数是多少,那么我们直接进行动态转移即可:f[u]=cnt[u]+max(f[v])其中v是u的子节点。
细节见代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
const int N=5e6+10;
int e[N],ne[N],h[N],idx;
int cnt[N];
long long f[N];//f[i]记录以i节点为根的子树中所有节点的mex之和的最大值
void add(int x,int y)
{
e[idx]=y;
ne[idx]=h[x];
h[x]=idx++;
}
void dfs(int x,int fa)
{
cnt[x]=1;
long long t=0;//记录子节点贡献最大值
for(int i=h[x];i!=-1;i=ne[i])
{
int j=e[i];
if(j==fa) continue;
dfs(j,x);
cnt[x]+=cnt[j];
t=max(f[j],t);
}
f[x]=cnt[x]+t;
}
int main()
{
int T;
cin>>T;
while(T--)
{
idx=0;
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) h[i]=-1;
int u,v;
for(int i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(1,-1);
printf("%lld\n",f[1]);
}
return 0;
}
边栏推荐
猜你喜欢
随机推荐
reduce()方法的学习和整理
图像处理、分析与机器视觉一书纠错笔记
记录vue-页面缓存问题
摆脱极域软件的限制
Email management Filter emails
LaTeX使用frame制作PPT图片没有标号
What is the website ICP record?
Tencent Internal Technology: Evolution of Server Architecture of "The Legend of Xuanyuan"
MySQL的主从模式搭建
Collision, character controller, Cloth components (cloth), joints in the Unity physics engine
Detailed explanation of the construction process of Nacos cluster
滚动条问题,未解决
单片机期末复习大题
DevOps流程demo(实操记录)
【8】Docker中部署Redis
【FAQ】What is Canon CCAPI
数组&的运算
网络排错基础-学习笔记
D46_Force applied to rigid body
BIO,NIO,AIO实践学习笔记(便于理解理论)








