E. Disjoint Path On Tree
Who is The 19th ZUCCPC Champion
https://ac.nowcoder.com/acm/contest/31533/A
题意
给定一棵 个节点的树,求解二元组 的个数,其中 是俩不相交的简单路径。
路径 与 视作同一路径。
制约
解答
显然,树上的路径均为简单路径,。容易知道 个节点的树的简单路径条数为:
而 与 视作一样的也没关系,求出所有二元组后除以二即可。
另一方面,所求也等价于 相交组数 ,设两条路径交于 ,即选择
讨论 的来源:
- ,即 。
- ,即 。
注意不能是两点均来自 。组合起来:
参考代码
注:其中
Z
为 jiangly 的整数模板类。
Z f(int n) { return 1LL * n * (n + 1) / 2; }
void solve() {
int n;
std::cin >> n;
std::vector<std::vector<int>> G(n);
for (int i = 1, u, v; i < n; ++i) {
std::cin >> u >> v;
-- u, -- v;
G[u].push_back(v);
G[v].push_back(u);
}
Z ans = f(n) * f(n);
std::vector<int> size(n);
std::function<void(int, int)> dfs = [&](int u, int p) {
size[u] = 1;
for (auto &&to : G[u]) if (to != p) {
dfs(to, u);
size[u] += size[to];
}
Z cnt1 = f(size[u]);
Z cnt2 = 1LL * size[u] * (n - size[u]);
for (auto &&to : G[u]) if (to != p) {
cnt1 -= f(size[to]);
}
ans -= (cnt1 + cnt2) * (cnt1 + cnt2) - cnt2 * cnt2;
};
dfs(0, -1);
std::cout << ans / 2 << '\n';
}
后寄
注:官方题解:
LCA 是什么东西,不是很懂,长大了再学。