Submission #677937

#TimeUsernameProblemLanguageResultExecution timeMemory
677937VictorRoad Closures (APIO21_roads)C++17
12 / 100
337 ms72044 KiB
// #pragma GCC target ("avx,avx2,fma")
// #pragma GCC optimize ("Ofast,inline") // O1 - O2 - O3 - Os - Ofast
// #pragma GCC optimize ("unroll-loops")

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (a); i < (b); ++i)
#define per(i, a, b) for (int i = (b - 1); i >= (a); --i)
#define trav(a, x) for (auto &a : x)

#define all(x) x.begin(), x.end()
#define sz(x) int(x.size())
#define pb push_back
#define debug(x) cout << #x << " = " << x << endl

#define umap unordered_map
#define uset unordered_set

typedef pair<int, int> ii;
typedef pair<int, ii> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<pll> vpll;

const int INF = 1'000'000'007;

ll n, k, vis[250001], deg[250001];
set<pll> graph[250001];
ll memo[250001][2], sums[250001];
vpll degree;
multiset<ll> pqs[250001];

void dp(ll u, ll p) {
    vis[u] = k;
    ll ans = sums[u];
    vll diff;

    trav(edge, graph[u]) if (edge.first != p) {
        ll v, w;
        tie(v, w) = edge;
        dp(v, u);
        ans += memo[v][0];
        diff.emplace_back((memo[v][1] + w) - memo[v][0]);
    }

    sort(all(diff));
    diff.emplace_back(1e17);
    memo[u][0] = memo[u][1] = 1e14;
    ll need_rem = max(0LL, deg[u] - k - (ll)sz(pqs[u]));
    umap<ll,int> added;

	int cnt=0;
    rep(i, 0, min(ll(sz(diff) - 1), need_rem)) {
        ll val = diff[i];
        ++added[val];
		++cnt;
        pqs[u].insert(val);
        ans += val;
    }

    if (cnt < need_rem)
        memo[u][1] = ans;
    else {
        // debug(u);
        rep(i, need_rem, sz(diff)) {
            memo[u][0] = min(memo[u][0], ans);
            memo[u][1] = min(memo[u][1], ans - max(0LL, *(--pqs[u].end())));

            ll val = diff[i];

            if (val < *(--pqs[u].end())) {
                ++added[val];
                ans += val;
                auto it = (--pqs[u].end());
                --added[*it];
                ans -= *it;
                pqs[u].erase(it);
                pqs[u].insert(val);

            } else if (val < 0)
                ans += val;
            else
                break;
        }
    }

    trav(item,added) {
		ll val;
		tie(val,cnt)=item;
		if(cnt<0) {
			cnt=-cnt;
			rep(i,0,cnt) pqs[u].insert(val);
			
		} else rep(i,0,cnt) pqs[u].erase(val);
	}

    // cout<<"u = "<<u+1<<" need_rem = "<<need_rem<<' '<<memo[u][0]<<' '<<memo[u][1]<<endl;
}

vector<long long> minimum_closure_costs(int N, vector<int> U, vector<int> V, vector<int> W) {
    n = N;
    memset(vis, -1, sizeof(vis));
    memset(deg, 0, sizeof(deg));
    memset(sums, 0, sizeof(sums));
    degree.assign(n, {0, 0});
    vll ans(n, 0);

    rep(i, 0, n - 1) {
        graph[U[i]].emplace(V[i], W[i]);
        graph[V[i]].emplace(U[i], W[i]);

        ++degree[U[i]].first;
        degree[U[i]].second = U[i];
        ++degree[V[i]].first;
        degree[V[i]].second = V[i];

        ++deg[U[i]];
        ++deg[V[i]];
    }

    sort(all(degree));
    ll removed = 0;
    rep(i, 0, n) {
        k = i;
        while (removed < n && degree[removed].first <= k) {
            int u = degree[removed].second;
            trav(edge, graph[u]) {
                ll v, w;
                tie(v, w) = edge;
                graph[v].erase({u, w});
                sums[v] += w;
                pqs[v].insert(w);
            }
            // debug(u+1);
            ++removed;
        }

        rep(j, removed, n) {
            ll u = degree[j].second;
            while (sz(pqs[u]) > deg[u] - k) {
                auto it = (--pqs[u].end());
                sums[u] -= *it;
                pqs[u].erase(it);
            }
        }

        rep(j, removed, n) if (vis[degree[j].second] != k) {
            ll u = degree[j].second;
            dp(u, u);
            ans[k] += memo[u][0];
        }
    }
    return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...