首页 > 其他分享 >P3478 STA-Station/换根 $dp$ 板子

P3478 STA-Station/换根 $dp$ 板子

时间:2024-09-24 20:12:46浏览次数:7  
标签:sz STA int pos 节点 fa Station 换根 dp

P3478 [POI2008] STA-Station

link

给定一个 \(n\) 个点的树,请求出一个结点,使得以这个结点为根时,所有结点的深度之和最大。

一个结点的深度之定义为该节点到根的简单路径上边的数量。

对于全部的测试点,保证 \(1 \leq n \leq 10^6\),\(1 \leq u, v \leq n\),给出的是一棵树。

思路:树形dp(换根dp)。

我们设1节点为根节点,并先统计完1节点的答案。

接下来设计状态转移方程:

我们设 \(dp_{pos}\) 为以 \(pos\) 为根节点时,所有节点到根节点的深度之和。

设 \(to\) 为 \(pos\) 节点的子节点,则可以得到状态转移方程:

\[dp_{to} = dp_{pos} + (n-sz_{to}) - sz_{to} \]

其中 \(sz_{to}\) 是指 \(to\) 节点的子树的大小。

\((n-sz_{to})\) 是移到 \(to\) 节点后,除了 \(to\) 的子树的节点外的节点到 \(to\) 节点的距离增加的值。

\(- sz_{to}\) 则是移到 \(to\) 节点后,\(to\) 的子树的所有节点到 \(to\) 节点距离减少的值。

则这个过程可以用两遍 \(dfs\) 来解决。

第一遍:统计以 \(1\) 节点为根节点时候的答案,并预处理 \(sz\) 数组。

void predfs(int pos,int fa,int dep){
	dp[1] += dep;
	for(int to : tree[pos]){
		if(to != fa){
			predfs(to,pos,dep + 1);
			sz[pos] += sz[to];
		}
	}
}

第二遍:直接使用状态转移方程转移,注意是从根节点往子节点 \(dp\) 。

void dfs(int pos,int fa){
	for(int to : tree[pos]){
		if(to != fa){
			dp[to] = dp[pos] + n - 2 * sz[to];
			dfs(to,pos);
		}
	}
}

最后遍历整个 \(dp\) 数组并且输出答案即可。

\({\Huge code:}\)

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define int long long
const int MAXN = 1e6 + 7;
vector<int> tree[MAXN];
int n;
int dp[MAXN];
int sz[MAXN];
void predfs(int pos,int fa,int dep){
	dp[1] += dep;
	for(int to : tree[pos]){
		if(to != fa){
			predfs(to,pos,dep + 1);
			sz[pos] += sz[to];
		}
	}
}
void dfs(int pos,int fa){
	for(int to : tree[pos]){
		if(to != fa){
			dp[to] = dp[pos] + n - 2 * sz[to];
			dfs(to,pos);
		}
	}
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i = 1;i < n;i++){
		int x,y;
		cin>>x>>y;
		tree[x].push_back(y);
		tree[y].push_back(x);
	}
	for(int i = 1;i <= n;i++) sz[i] = 1;
	predfs(1,0,1);
	dfs(1,0);
	int ans = 0,id = 1;
	for(int i = 1;i <= n;i++){
		if(dp[i] > ans){
			ans = dp[i],id = i;
		}
	}
	cout<<id;
	return 0;
}

复杂度 \({\Large O(n)}\),可以通过本题。

标签:sz,STA,int,pos,节点,fa,Station,换根,dp
From: https://www.cnblogs.com/wyl123ly/p/18429924

相关文章

  • OpenHarmony 的启动子系统startup与init组件
    1.rk3568的startup配置配上initcomponent以后,系统就会编译集成这个组件。vendor/hihope/rk3568/config.json{"subsystem":"startup","components":[{"component":"init","fea......
  • fastapi
    fastapihttps://fastapi.tiangolo.com/zh/learn/0快速使用#异步框架fromfastapiimportFastAPIfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strage:[email protected]('/')asyncdefindex():return{'code......
  • 15.8 在k8s部署prometheus statefulset
    本节重点介绍:检查,kube-systemns[root@prome-master01prometheus]#kubectlgetpod-nkube-systemNAMEREADYSTATUSRESTARTSAGEcoredns-7d75679df-7f7tx1/1Running088mcoredns-7d75679df-qmzbg1/1Running088metcd-prome-master011/1Running088mkube-apise......
  • 15.7 创建prometheus的statsfulset配置
    本节重点介绍:prometheusstatsfulsetyaml配置设置statsfulset副本反亲和性设置pod运行优先级设置volumeClaimTemplates设置配置文件热更新容器configmap-reload设置prometheus主容器statsfulset设置元信息apiVersion:apps/v1kind:StatefulSetmetadata:name:prometheus......
  • 在Linux 中使用 pidstat 命令监控进程性能
    一、安装pidstat命令检查系统是否已经安装了pidstat打开终端,输入以下命令检查是否已经安装了pidstat:pidstat-V如果显示版本信息,说明已经安装,可以跳过安装步骤。如果提示找不到命令,那么继续下一步安装。更新包管理器在安装pidstat前,建议先更新系统的包管理器来获......
  • Python中,你可以使用`scipy.stats`库中的`entropy`函数来计算两个连续变量之间的KL散度
    在Python中,你可以使用`scipy.stats`库中的`entropy`函数来计算两个连续变量之间的KL散度。这个函数计算的是两个概率分布之间的熵,即KL散度。以下是一个使用`scipy`计算KL散度的示例:首先,你需要安装`scipy`库(如果还未安装的话):```bashpipinstallscipy```然后,你可以使用以下代码......
  • 中国大陆用户如何使用Jetbrains内置的AI插件AI Assistant
    1安装AIAssistant插件AI功能依赖AIAssistant插件:2功能解释代码、回答有关代码片段的问题、提交消息等等。在需要时更快地编码AIAssistant可以自动补全单行、函数和整个代码块,并与您的编码样式、项目上下文和命名约定保持一致。AIAssistant还可以根据您的自然语言提......
  • 基于SqlAlchemy+Pydantic+FastApi的Python开发框架
    随着大环境的跨平台需求越来越多,对与开发环境和实际运行环境都有跨平台的需求,Python开发和部署上都是跨平台的,本篇随笔介绍基于SqlAlchemy+Pydantic+FastApi的Python开发框架的技术细节,以及一些技术总结。最近这几个月一直忙于Python开发框架的整合处理,将之前开发框架中很多重要......
  • OpenStack基础平台部署案例
    OpenStack基础平台部署案例案例描述本案例是讲述如何使用云主机搭建OpenStack云平台。包括两种搭建的方式,一种是直接执行脚本安装,另一种是使用Ansible安装。使用这种方式,不需要重复安装系统去搭建平台,只需要创建云主机去构建OpenStack云平台,使用云主机去练习相应的操作。案......
  • 绘制印章的开源工具DrawStampUtils使用
    最近写了一个绘制印章的工具DrawStampUtils,具有比较完整的印章修改效果,定制化度较高,git地址(https://github.com/xxss0903/drawstamputils),也可以在npmjs中搜索DrawStampUtils即可//将要绘制的canvas组件的引用传入,还有就是对应的毫米转像素的大小传入即可conststampCanva......