P3478 [POI2008] STA-Station

题面

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

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

分析

本题可以用树形DP做。

首先,把树按照链式前向星的方法保存。

然后考虑第 i 个点的深度来DP,先求 DP1,然后往下推,深度减小了 sizev,增加了 nsizev。所以用 O(n) 的算法来DP,然后直接用 O(n) 统计最大值。

贴上代码

#include<bits/stdc++.h>
using namespace std;

const int N = 1e6+10;
struct Edge{
	int next,to;
} e[N<<1];

int deep[N],head[N],length;
int siz[N];
long long dp[N];
int n,a,b;
int result=0;

void add(int u,int v){
	e[++length].to=v;
	e[length].next=head[u];
	head[u]=length;
}

void dymanic_planning(int u,int fa){
	siz[u]=1;
	dp[u]=deep[u];
	for(int i=head[u];i;i=e[i].next){
        int v=e[i].to;
        if(v==fa)continue;
        deep[v]=deep[u]+1;
        dymanic_planning(v,u);
        siz[u]+=siz[v];
        dp[u]+=dp[v];
    }
}

void solve(int u,int fa){
    for(int i=head[u];i;i=e[i].next){
        int v=e[i].to;
        if(v==fa)continue;
        dp[v]=dp[u]-siz[v]+n-siz[v];
        solve(v,u);
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	cin>>n;
	for(int i=0;i<n-1;i++){
		cin>>a>>b;
		add(a,b);
		add(b,a);
	}
	dymanic_planning(1,0);
	solve(1,0);
	for(int i=1;i<=n;i++){
		if(dp[result]<dp[i]){
			result=i;
		}
	}cout<<result<<endl;
	return 0;
}
posted @   蒟蒻xiezheyuan  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示