传送门
// 题意: 给定一颗树, 定义一个点的繁荣度为经过这个点的路径的条数, 求这棵树的最大繁荣度为多少. 注意叶子结点路径数为0.
// 思路: 我们首先要知到一个节点的繁荣度怎么算, 它 = 该节点的所有子树之间(size大小)两两相乘再相加的答案, 不要因为一次dfs而算不出其他子树的大小而困扰, 那是因为你没想到这是一棵树, 所以我们直接用总节点数减去该子树的大小就是剩余没算的节点个数了!!! . 所以我们直接从任意一点开始dfs, 每次从一个节点的子树回来的时候就累加一遍答案, 离开该节点的时候更新一遍ans. 最后一定可以得出那个最优的答案.
AC Code
const int maxn = 2e4+5;
struct node {
int to, next;
}e[maxn<<1];
int cnt, head[maxn];
void add(int u, int v) {
e[cnt] = node{v, head[u]};
head[u] = cnt++;
}
int sz[maxn];
int ans = 0, n ;
void dfs(int u, int fa) {
int res = 0 ;
sz[u] = 1;
for (int i = head[u] ; ~i ; i = e[i].next) {
int to = e[i].to;
if (to == fa) continue;
dfs(to, u);
sz[u] += sz[to];
res += (n - sz[u] ) * sz[to];
}
ans = max(ans, res);
}
void solve(){
cin >> n;
cnt = 0; Fill(head, - 1); Fill(sz, 0);
ans = 0;
for (int i = 1 ; i < n ; i++) {
int u ,v;
cin >> u >> v ;
add(u, v);
add(v, u);
}
dfs(1 , -1);
cout << ans << endl;
}