题解 P2052 【[NOI2011]道路修建】

kradcigam

2020-05-16 10:08:02

Solution

首先对于一棵树,他肯定是一个**连通图**。 所以,对于一条边 $(x,y)$,$x$ 连的节点个数 $-$ $y$ 连的节点个数 $=$ $($ $n$ $-$ $y$ 连的节点个数 $)$ $-$ $y$ 连的节点个数 因为这张图是连通的,所以**所有节点不在 $x$ 那端,就在 $y$ 那端**。 我们回到树,我们可以 $O(n)$ 的时间遍历一遍树,并求出 $size$。 大家可以看看我的代码 ```cpp #include <bits/stdc++.h> using namespace std; typedef long long ll; template<typename T>inline void read(T &FF) { T RR = 1; FF = 0; char CH = getchar(); for (; !isdigit(CH); CH = getchar())if (CH == '-')RR = -1; for (; isdigit(CH); CH = getchar())FF = (FF << 1) + (FF << 3) + (CH ^ 48); FF *= RR; } const int N = 1e6 + 10; vector<pair<int, int> >v[N]; ll sz[N], ans, n; void dfs(int x, int fa) { sz[x] = 1;//求size for (auto i : v[x]) { if (i.first != fa) { dfs(i.first, x); sz[x] += sz[i.first]; ans += 1ll * i.second * abs(sz[i.first] - (n - sz[i.first]));//上面的方法 } } } int main() { read(n); for (int i = 1; i < n; i++) { int x, y, z; read(x); read(y); read(z); v[x].push_back(make_pair(y, z)); v[y].push_back(make_pair(x, z)); } dfs(1, 0); cout << ans; return 0; } ```