POJ1655 Balancing Act 题解

CSDN同步

原题链接

简要题意:

给定一棵树,求它的重心,以及 以它为根的最大子树的大小。

重心的定义:\(i\) 为根的最大子树最小的 \(i\) 编号。

首先扫清一个误区:

初阶的 \(\texttt{Oier}\) 可能觉得,那重心就是叶子节点了?

不是这样的。如果把叶子结点拿起来作为根,那么 除叶子结点外的其它所有节点都是一个子树,所以 一般来说 叶子结点并不是重心。(也不排除深度 \(=2\) 的情况)

那么,其实以 \(i\) 为根的最大子树分为两部分:

  1. 当前以 \(i\) 为根的子树个数(包括自己),记作 \(d_i\).

  2. 不包含在 \(i\) 为根的子树中的,即 \(sum - d_i\).(\(sum\) 表示一共有多少个点)

显然,我么可以用一重 \(\text{dfs}\) 求出 \(d_i\),然后打擂即可得出。

细节:\(sum \not = n\),只是节点 \(\leq n\),不一定会出现。

时间复杂度:\(O(n)\).

实际得分:\(100pts\).

#pragma GCC optimize(2)
#include
#include
#include //memset 在这个库里
#include
#include //POJ 不支持万能头,只能手写
using namespace std;

const int N=2e5+1;

inline int read(){char ch=getchar();int f=1; while(!isdigit(ch)) {if(ch=='-') f=-f; ch=getchar();}
	   int x=0;while(isdigit(ch)) x=x*10+ch-'0',ch=getchar(); return x*f;}

int n,mini,minh,T;
int d[N];
vector G[N];

inline int dfs(int dep,int fa) {
	d[dep]=0; int t=0;
	for(int i=0;i

你可能感兴趣的:(POJ1655 Balancing Act 题解)