7.17每日一題題解
阿新 • • 發佈:2020-07-17
樹上求和
涉及知識點:
- 貪心
- 圖論
- dfs
solution:
- 我們只需要計算出每條邊被經歷過了多少次
- 每條邊被經過的次數等於這條邊分隔開的兩端點分別所在的連通塊大小相乘
- 然後把這些次數按照從小到達或者從大到小排序
- 我是從小到大,那麼次數小的邊就應該賦值為(n - i + 1)
std:
#include <iostream> #include <vector> #include <algorithm> using namespace std; typedef long long LL; const int N = 1e5 + 10; vector<int>v[N]; LL son[N]; int n; void dfs(int u,int f) { int sum = 0; for(auto &x : v[u]) { if(x == f){ continue; } dfs(x,u); sum += son[x]; } son[u] = sum + 1; } int main() { cin >> n; for(int i = 0;i < n - 1;i ++) { int a,b; cin >> a >> b; v[a].push_back(b); v[b].push_back(a); } dfs(1,0); for(int i = 1;i <= n;i ++) { son[i] = (n - son[i]) * son[i]; } sort(son + 1,son + n + 1); LL ans = 0; for(int i = 1;i <= n;i ++) { ans += (n - i + 1) * son[i]; } cout << ans << endl; return 0; }