2021.08.06 P3478 STA-Station(树形结构)

[P3478 POI2008]STA-Station - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题意:

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

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

分析:

设x的父节点为y,则根节点从y移到x:

\[f[x]=f[y]-size[x]+(n-size[x]) \\ f[x]=f[y]+n-2*szie[x] \]

代码如下:

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;

#define int long long
const int N=1e6+10;
int n,cnt,head[N],fa[N],size[N],f[N],dep[N];
struct node{
	int to,next;
}a[N*2];

inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*w;
}
void add(int u,int v){
	++cnt;
	a[cnt].to=v;
	a[cnt].next=head[u];
	head[u]=cnt;
}
void dfs(int x,int fai){
	dep[x]=dep[fai]+1;
	fa[x]=fai;
	size[x]=1;
	for(int i=head[x];i;i=a[i].next){
		int v=a[i].to;
		if(v==fai)continue;
		dfs(v,x);
		size[x]+=size[v];
	}
}
void solve(int x){
	for(int i=head[x];i;i=a[i].next){
		int v=a[i].to;
		if(fa[x]==v)continue;
		f[v]=f[x]-size[v]+(n-size[v]);
		solve(v);
	}
}

signed main(){
	n=read();
	for(int i=1;i<n;i++){
		int u,v;
		u=read();v=read();
		add(u,v);add(v,u);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++)f[1]+=dep[i];
	//for(int i=1;i<=n;i++)cout<<size[i]<<" ";cout<<endl<<endl;
	solve(1);
	//for(int i=1;i<=n;i++)cout<<f[i]<<" ";cout<<endl<<endl;
	int ans=1;
	for(int i=1;i<=n;i++)if(f[ans]<f[i])ans=i;
	cout<<ans;
	return 0;
}
 posted on 2021-08-06 17:06  eleveni  阅读(47)  评论(0)    收藏  举报