因为是最远点,故必定为直径。
我们知道树的直径并不为一。但是考虑一下,如果一棵树的直径中有奇数个结点,其实对于它来说其“中心结点”是
每一条直径都必须通过的。(证明靠脑子)
由上面那个想法我们可以类比出偶数结点的情况,那么其“中心”将会变成一条边,也就是说这条边两边的点是必被
直径通过的存在。
所以,当结点为偶数时,只需要分别计算两侧结点所领导的子树中有多少个结点的深度是直径的一半即可。
但是在结点数为奇数个时问题就会有转变,因为类似于“菊花图”这种的,其实它隐含了一个组合问题,是:组间
可以同时出现,而组内不能同时出现,且至少要出现两个结点,问有多少种选择点的集合的方式。
我们可以考虑的是由于“组内互斥”(不能同时出现)所以对于一个大小为 x 的组,它可以选择的结点有 x+1 种
(因为可以不选)那么在满足“组内互斥”前提下总的选择方案为 (x1+1)*(x2+1)*(x3+1)*…*(xm+1) 其中 m 是
组数。
但是在上述选择下我们并没有考虑“至少出现两个结点”的条件,我们计算的是出现零个、一个、两个……一直到出
现 m 个的情况,那么我们只需要删除出现零个和一个的情况就可以了,其分别为 1 和 x1+x2+…+xm 种情况。
#include<bits/stdc++.h>usingnamespace std;#definelllonglong#define_for(i, a, b)for(int i =(a); i <=(b); i ++)inlinevoidread(int&x,int&y){
scanf("%d%d",&x,&y);}int mod =998244353;int n;int head[200009], nex[400009], to[400009], tot;/// 链式前向星建树 voidadd(int x,int y){
nex[++ tot]=