제출 #1336168

#제출 시각아이디문제언어결과실행 시간메모리
1336168DanielPr8도로 폐쇄 (APIO21_roads)C++20
7 / 100
2094 ms39568 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvl = vector<vll>;
using pll = pair<ll,ll>;
using vpl = vector<pll>;
using vvp = vector<vpl>;
using vi = vector<int>;
#define f first
#define s second
#define pb push_back
#define all(v) v.begin(),v.end()
vll dp, dp1;
vvp g, gr;vvl sm, rm;

void dfs(ll cur, ll pr, ll k){
    priority_queue<ll,vll,greater<ll>> pq;
    for(auto [i,e]: g[cur]){
        if(i!=pr){
            dfs(i,cur,k);
            dp1[cur]+=dp[i];
            pq.push(dp1[i]-dp[i]+e);
        }
    }
    ll cnt=0;
    while(!pq.empty() && (pq.top()<0 || g[cur].size()-cnt-1>k)){
        auto v = pq.top();
        pq.pop();
        dp1[cur]+=v;
        cnt++;
    }
    dp[cur]=dp1[cur];
    while(!pq.empty() && (pq.top()<0 || g[cur].size()-cnt>k)){
        auto v = pq.top();
        pq.pop();
        dp[cur]+=v;
        cnt++;
    }
}
void dfs2(ll cur, ll pr, ll k){
    priority_queue<ll,vll,greater<ll>> pq;
    for(auto [i,e]: gr[cur]){
        if(i!=pr){
            dfs2(i,cur,k);
            dp1[cur]+=dp[i];
            pq.push(dp1[i]-dp[i]+e);
        }
    }
    ll cnt=g[cur].size()-k-1, t=0;
    while(!pq.empty() && (pq.top()<0 || cnt>0)){
        auto v = pq.top();
        pq.pop();

        ll nx = upper_bound(all(sm[cur]),v)-sm[cur].begin();
        nx = min(t+cnt,nx);
        cnt -= (nx-t);
        dp1[cur] += rm[cur][nx]-rm[cur][t];
        t=nx;
        if(cnt>0 || v<0){
            dp1[cur]+=v;
            cnt--;
        }
    }
    cnt++;
    dp[cur]=dp1[cur];
    while(!pq.empty() && (pq.top()<0 || cnt>0)){
        auto v = pq.top();
        pq.pop();

        ll nx = upper_bound(all(sm[cur]),v)-sm[cur].begin();
        nx = min(t+cnt,nx);
        cnt -= (nx-t);
        dp[cur] += rm[cur][nx]-rm[cur][t];
        t=nx;
        if(cnt>0 || v<0){
            dp[cur]+=v;
            cnt--;
        }
    }
}



std::vector<long long> minimum_closure_costs(int n, vi u, vi v, vi w) {
    gr=g = vvp(n);
    vll ans(n);
    ll B = 2;
    rm=sm = vvl(n);
    B = min<ll>(B,n-1);
    for(ll i = 0; i < n-1; ++i){
        ans[0]+=w[i];
        g[u[i]].pb({v[i],w[i]});
        g[v[i]].pb({u[i],w[i]});
    }
    vll las(n-1,1);
    for(ll i = 1; i <= B; ++i){
        dp=dp1=vll(n);
        dfs(0,0,i);
        ans[i]=dp[0];
    }
    vll big;
    for(ll i = 0; i < n; ++i){
        if(g[i].size()>B){
            big.pb(i);
            for(auto [j,v]: g[i]){
                if(g[j].size()>B){
                    gr[i].pb({j,v});
                }
                else sm[i].pb(v);
            }
            sort(all(sm[i]));
            sm[i].pb(1e10);
            rm[i]={0};
            for(ll j = 0; j < sm[i].size(); ++j){
                rm[i].pb(rm[i][j]+sm[i][j]);
            }
        }
    }
    for(ll i = B+1; i < n; ++i){
        for(ll j: big){
            dp[j]=-1;
            dp1[j]=0;
        }
        for(ll j: big){
            if(dp[j]==-1){dfs2(j,j,i);ans[i]+=dp[j];}
        }
    }
    return ans;
}


// int main() {
//   int N;
//   assert(1 == scanf("%d", &N));

//   vi U(N - 1), V(N - 1), W(N - 1);
//   for (int i = 0; i < N - 1; ++i) {
//     assert(3 == scanf("%d %d %d", &U[i], &V[i], &W[i]));
//   }

//   std::vector<long long> closure_costs = minimum_closure_costs(N, U, V, W);
//   for (int i = 0; i < static_cast<int>(closure_costs.size()); ++i) {
//     if (i > 0) {
//       printf(" ");
//     }
//     printf("%lld",closure_costs[i]);
//   }
//   printf("\n");
//   return 0;
// }
#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...