Submission #1334139

#TimeUsernameProblemLanguageResultExecution timeMemory
1334139windowwifeRoad Closures (APIO21_roads)C++20
100 / 100
105 ms43520 KiB
#ifndef rtgsp
#include "roads.h"
#endif // rtgsp

#include<bits/stdc++.h>
#define ll long long
#define task ""
using namespace std;
const ll maxn = 3e5 + 4, LG = 20, inf = 1e18;
int n, deg[maxn], visited[maxn];
ll dp[maxn][2];
vector<int> event[maxn], active;
vector<ll> ans;
bool imp[maxn];
struct Edge
{
    int v, w, id, rev;
    Edge (int _v = 0, int _w = 0, int _id = 0, int _rev = 0)
    {
        v = _v; w = _w; id = _id; rev = _rev;
    }
    bool operator < (const Edge& other) const
    {
        if (w != other.w) return w < other.w;
        return v < other.v;
    }
};
vector<Edge> adj[maxn];

struct BIT
{
    int n, cnt;
    vector<ll> fw[2];
    BIT (int _n = 0)
    {
        n = _n;
        cnt = 0;
        fw[0].clear(); fw[1].clear();
        fw[0].resize(n + 1, 0);
        fw[1].resize(n + 1, 0);
    }
    void upd (int x, int val)
    {
        ++cnt;
        for (; x <= n; x += (x & (-x)))
        {
            ++fw[0][x];
            fw[1][x] += val;
        }
    }
    ll kth (int k)
    {
        ll res = 0;
        int pos = 0;
        for (int i = LG; i >= 0; i--)
        {
            if (pos + (1 << i) <= n && fw[0][pos + (1 << i)] <= k)
            {
                pos += (1 << i);
                k -= fw[0][pos];
                res += fw[1][pos];
            }
        }
        return res;
    }
};
vector<BIT> fw;

void dfs (int u, int p, int k)
{
    visited[u] = k;
    int sz = 0;
    for (int j = 0; j < (int)adj[u].size(); j++)
    {
        if (imp[adj[u][j].v])
        {
            adj[u][sz++] = adj[u][j];
        }
    }
    adj[u].resize(sz);
    ll base = 0;
    int done = 0;
    vector<ll> diff;
    diff.clear();
    for (Edge e : adj[u])
    {
        if (e.v == p) continue;
        dfs(e.v, u, k);
        ll keep = dp[e.v][0], del = min(dp[e.v][1] + e.w, inf);
        if (keep == inf || del <= keep)
        {
            base = min(base + del, inf);
            ++done;
        }
        else
        {
            base = min(base + keep, inf);
            diff.push_back(del - keep);
        }
    }
    sort(diff.begin(), diff.end());
    for (int x = 0; x < 2; x++)
    {
        int need = max(0, max(0, deg[u] - k) - x - done);
        //cout << "tongue " << x << " " << need << endl;
        ll mn = inf, cur = base;
        for (int j = 0; j <= (int)diff.size(); j++)
        {
            int cnt = max(0, need - j);
            //cout << "owowowowowowo " << j << " " << cnt << " " << fw[u].cnt << " " << cur << " " << fw[u].kth(cnt) << endl;
            if (cnt <= fw[u].cnt)
            {
                mn = min(mn, cur + fw[u].kth(cnt));
            }
            if (j < (int)diff.size())
            {
                cur = min(cur + diff[j], inf);
            }
        }
        dp[u][x] = mn;
    }
    //cout << u << " " << dp[u][0] << " " << dp[u][1] << endl;
}

vector<ll> minimum_closure_costs (int N, vector<int> U, vector<int> V, vector<int> W)
{
    n = N;
    for (int i = 0; i < n - 1; i++)
    {
        ++U[i]; ++V[i];
        adj[U[i]].push_back({V[i], W[i], 0, 0});
        adj[V[i]].push_back({U[i], W[i], 0, 0});
        ++deg[U[i]];
        ++deg[V[i]];
    }
    fw.push_back(BIT(0));
    for (int i = 1; i <= n; i++)
    {
        fw.push_back(BIT((int)adj[i].size()));
        event[deg[i]].push_back(i);
        visited[i] = -1;
        active.push_back(i);
        imp[i] = true;
        sort(adj[i].begin(), adj[i].end());
        for (int j = 0; j < (int)adj[i].size(); j++)
        {
            adj[i][j].id = j + 1;
        }
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 0; j < (int)adj[i].size(); j++)
        {
            auto it = lower_bound(adj[adj[i][j].v].begin(), adj[adj[i][j].v].end(), Edge(i, adj[i][j].w, 0, 0));
            adj[i][j].rev = it->id;
        }
    }
    ans.resize(n, 0);
    for (int k = 0; k < n; k++)
    {
        //cout << k << endl;
        for (int u : event[k])
        {
            imp[u] = false;
            for (Edge e : adj[u])
            {
                if (imp[e.v])
                    fw[e.v].upd(e.rev, e.w);
            }
        }
        int sz = 0;
        for (int j = 0; j < (int)active.size(); j++)
        {
            if (imp[active[j]])
            {
                active[sz++] = active[j];
            }
        }
        active.resize(sz);
        for (int u : active)
        {
            if (visited[u] != k)
            {
                dfs(u, 0, k);
                //cout << dp[u][0] << endl;
                ans[k] += dp[u][0];
            }
        }
    }
    return ans;
}

#ifdef rtgsp
int main ()
{
    //freopen(task".INP", "r", stdin);
    //freopen(task".OUT", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int N, u, v, w;
    vector<int> U, V, W;
    cin >> N;
    for (int i = 1; i < N; i++)
    {
        cin >> u >> v >> w;
        U.push_back(u); V.push_back(v); W.push_back(w);
    }
    auto ans = minimum_closure_costs(N, U, V, W);
    for (ll x : ans) cout << x << " ";
}
#endif // rtgsp

#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...