Codeforces Round #635 (Div. 2)C. Linova and Kingdom

n個點的樹型結構,選擇k個工業城市,其他都是旅遊城市,問所有工業城市到1節點的幸福值總和最大多少。幸福值爲經過的旅遊城市的個數。
優先的想法肯定是深度越大越好。
但是考慮一下,對於一棵樹的內部節點而言,一定要經過根u,如果根被選爲工業城市,那麼增加的幸福值就是dep[u]-siz[u]
什麼意思呢?就是如果選了這個節點爲工業城市,那麼子樹內部的工業城市的幸福值都要減少1,
之所以減去的是樹的大小,是因爲基於深度越大越好,所以肯定是優先把樹內部的點選上,而增加的就是u到節點1的路徑長度也就是深度。
首先以dep[x]-siz[x]從大到小排序取前k大的和即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<int> e[1 << 21];
int siz[1 << 21], dep[1 << 21];
int cnt[1 << 21];
void dfs(int x, int f)
{
    dep[x] = dep[f] + 1;
    siz[x] = 1;
    for (auto it : e[x])
    {
        if (it == f)
            continue;
        dfs(it, x);
        siz[x] += siz[it];
    }
}
int main()
{
    int n, k;
    cin >> n >> k;
    for (int i = 1; i < n; i++)
    {
        int x, y;
        cin >> x >> y;
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs(1, -1);
    for (int i = 1; i <= n; i++)
        cnt[i] = i;
    sort(cnt + 1, cnt + 1 + n, [](int x, int y) {
        return dep[x] - siz[x] > dep[y] - siz[y];
    });
    ll ans = 0;
    for (int i = 1; i <= k; i++)
    {
        ans += dep[cnt[i]] - siz[cnt[i]];
    }
    cout << ans << endl;

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章