牛客小白月赛42.F 火凤燎原
火凤燎原
题意
规定蒲公英为原树上的一个连通块,满足:
- 有且一个中心点。
- 设中心点在原树中的度为 \(k(k \ge 3)\) ,则必须有 \(k-1\) 个结点在蒲公英上是一个叶子,剩下一条链,长度至少为 \(2\) (不包括中心点) 。
两个蒲公英不相同,当且仅当存在一个点,在其中一个蒲公英上而不在另一个蒲公英上。
如图为中心点 \(0\) 的一个蒲公英。
给定一棵无根树,求书上的蒲公英数量。
分析
假设给定的树结点数量为 \(n\) 。
对于某一个点,假设它的度为 \(d\) ,那么把这个点作为中心点的数量一共有 \(n - d - 1\) 个。
证明:因为中心点定了,所以要使蒲公英不同,只能改变它的链,对于除了这 \(d+1\) 个点的任意其他一个点,一定能与这个连通块的唯一一个点联通形成一条链。并且路径是唯一的,所以不同的链个数为 \(n - (d+1)\) 。
枚举每一个中心点即可。
Code
#include <iostream>
using namespace std;
const int N = 500010;
int d[N];
int main ()
{
cout.tie(0)->sync_with_stdio(0);
int T; cin >> T; while(T--)
{
int n; cin >> n;
for (int i = 1; i <= n; i ++ ) d[i] = 0;
for (int i = 1; i < n; i ++ )
{
int u, v; cin >> u >> v;
++ d[u], ++ d[v];
}
long long ret = 0;
for (int i = 1; i <= n; i ++ )
if (d[i] >= 3) ret += n - d[i] - 1;
cout << ret << endl;
}
return 0;
}