Submission #421086

#TimeUsernameProblemLanguageResultExecution timeMemory
421086wiwihoRoad Closures (APIO21_roads)C++14
100 / 100
653 ms52788 KiB
#include "roads.h"

#include <bits/stdc++.h>
#include <bits/extc++.h>

#define StarBurstStream ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define iter(a) a.begin(), a.end()
#define riter(a) a.rbegin(), a.rend()
#define lsort(a) sort(iter(a))
#define gsort(a) sort(riter(a))
#define pb(a) push_back(a)
#define eb(a) emplace_back(a)
#define pf(a) push_front(a)
#define ef(a) emplace_front(a)
#define pob pop_back()
#define pof pop_front()
#define mp(a, b) make_pair(a, b)
#define F first
#define S second
#define mt make_tuple
#define gt(t, i) get<i>(t)
#define tomax(a, b) ((a) = max((a), (b)))
#define tomin(a, b) ((a) = min((a), (b)))
#define topos(a) ((a) = (((a) % MOD + MOD) % MOD))
#define uni(a) a.resize(unique(iter(a)) - a.begin())
#define printv(a, b) {bool pvaspace=false; \
for(auto pva : a){ \
    if(pvaspace) b << " "; pvaspace=true;\
    b << pva;\
}\
b << "\n";}

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>;

const ll MOD = 1000000007;
const ll MAX = 1LL << 60;

template<typename A, typename B>
ostream& operator<<(ostream& o, pair<A, B> p){
    return o << '(' << p.F << ',' << p.S << ')';
}

ll ifloor(ll a, ll b){
    if(b < 0) a *= -1, b *= -1;
    if(a < 0) return (a - b + 1) / b;
    else return a / b;
}

ll iceil(ll a, ll b){
    if(b < 0) a *= -1, b *= -1;
    if(a > 0) return (a + b - 1) / b;
    else return a / b;
}

struct OwO;
ostream& operator<<(ostream& o, OwO& owo);

struct OwO{
    multiset<ll> large, small;
    ll sum = 0;
    void insert(ll v){
        if(!small.empty() && v < *small.rbegin()) small.insert(v), sum += v;
        else large.insert(v);
    }
    void erase(ll v){
        if(large.find(v) != large.end()){
            large.erase(large.find(v));
            return;
        }
        small.erase(small.find(v));
        sum -= v;
    }
    ll query(int k){
        while(small.size() < k && !large.empty()){
            small.insert(*large.begin());
            sum += *large.begin();
            large.erase(large.begin());
        }
        while(small.size() > k){
            large.insert(*small.rbegin());
            sum -= *small.rbegin();
            small.erase(prev(small.end()));
        }
        return sum;
    }
};

ostream& operator<<(ostream& o, OwO& owo){
    o << "s: ";
    for(int i : owo.small) o << i << " ";
    o << "l: ";
    for(int i : owo.large) o << i << " ";
    o << "sum: " << owo.sum;
    return o;
}

int n;
vector<vector<pii>> g;
vector<vector<pii>> tg;
vector<ll> sum;
vector<OwO> owo;
vector<bool> ok;
vector<int> okv;
vector<bool> vst;

int k;

pll dfs(int now, int p, int w){
    ll ts = sum[now];
    vst[now] = true;
    vector<ll> tmp;
    for(pii i : g[now]){
        if(i.F == p) continue;
        pll t = dfs(i.F, now, i.S);
        ts += t.S;
//        cerr << "r " << now << ' ' << i.F << " " << t << " " << ts << "\n";
        tmp.eb(min(0LL, t.F - t.S));
    }
    for(ll i : tmp) owo[now].insert(i);
    ll ans1 = MAX, ans2 = MAX;
    if(k != 0) ans1 = ts + owo[now].query(k - 1);
    ans2 = ts + owo[now].query(k) + w;
//    cerr << "dp " << now << " " << mp(ans1, ans2) << " " << sum[now] << " " << ts << " " << owo[now] << "\n";
    for(ll i : tmp) owo[now].erase(i);
    return mp(ans1, ans2);
}

ll solve(int K){
    k = K;
    ll ans = 0;
    for(int i : okv){
        if(vst[i]) continue;
        ans += dfs(i, i, 0).S;
    }
    for(int i : okv) vst[i] = false;
    return ans;
}

vector<ll> minimum_closure_costs(int N, vector<int> U, vector<int> V, vector<int> W){
    n = N;
    g.resize(n);
    tg.resize(n);
    sum.resize(n);
    owo.resize(n);
    ok.resize(n);
    vst.resize(n);

    for(int i = 0; i < n - 1; i++){
        int u = U[i], v = V[i], w = W[i];
        tg[u].eb(mp(v, w));
        tg[v].eb(mp(u, w));
        sum[u] += w;
        sum[v] += w;
        owo[u].insert(-w);
        owo[v].insert(-w);
    }

    vector<vector<int>> deg(n + 1);
    for(int i = 0; i < n; i++) deg[tg[i].size()].eb(i);

    vector<ll> ans(n);
    for(int i = n - 1; i >= 0; i--){
        for(int j : deg[i + 1]){
            ok[j] = true;
            okv.eb(j);
            for(pii v : tg[j]){
                sum[v.F] -= v.S;
                owo[v.F].erase(-v.S);
                g[v.F].eb(mp(j, v.S));
            }
        }

//        cerr << "test " << i << "\n";
//        printv(okv, cerr);
//        for(int j : okv){
//            cerr << j << " " << sum[j] << "  ";
//            printv(g[j], cerr);
//        }

        ans[i] = solve(i);
    }

    return ans;
}

Compilation message (stderr)

roads.cpp: In member function 'll OwO::query(int)':
roads.cpp:84:28: warning: comparison of integer expressions of different signedness: 'std::multiset<long long int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   84 |         while(small.size() < k && !large.empty()){
      |               ~~~~~~~~~~~~~^~~
roads.cpp:89:28: warning: comparison of integer expressions of different signedness: 'std::multiset<long long int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   89 |         while(small.size() > k){
      |               ~~~~~~~~~~~~~^~~
#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...