【每日一题】Treepath
Treepath
https://ac.nowcoder.com/acm/problem/14248
Solution
简单的树形dp。
设为点的子树中,以为端点且长度模为的路径数量。
考虑如何合并点的孩子的结果,因为从的子树内走到的路程比到的路程长个单位,
所以有:
其中、为合并后的结果;
原先已有条以为端点长度为偶数的路径,与条以为端点长度为奇数的路径合并可以得到条长度为偶数的路径;
同理,原先已有条以为端点长度为奇数的路径,与条以为端点长度为偶数的路径合并可以得到条长度为偶数的路径。
做一遍dfs即可求得结果,总复杂度。
Code
#include <bits/stdc++.h> using namespace std; using ll = long long; vector<int> G[100005]; int dp[100005][2]; ll ans = 0; void dfs(int u, int f) { dp[u][0] = 1; for (auto v : G[u]) { if (v != f) { dfs(v, u); for (int i = 0; i < 2; i++) { ans += 1ll * dp[u][i] * dp[v][i ^ 1]; dp[u][i] += dp[v][i ^ 1]; } } } } int main() { cin.sync_with_stdio(false), cin.tie(nullptr); int n; cin >> n; for (int i = 0; i < n - 1; i++) { int x, y; cin >> x >> y; G[x].push_back(y); G[y].push_back(x); } dfs(1, -1); cout << ans << "\n"; }