Submission #1141139

#TimeUsernameProblemLanguageResultExecution timeMemory
1141139byunjaewoo도로 폐쇄 (APIO21_roads)C++20
100 / 100
308 ms69576 KiB
#include "roads.h"
#include <bits/stdc++.h>
using namespace std;
using ll=long long;

const int N=100010;
int n, deg[N], par[N], pw[N];
ll dp[N], ep[N];
bool chk[N];
vector<int> v[N], c;
vector<pair<int, int>> st1[N], st2[N];
vector<pair<int, int>> adj[N], adj2[N];
ll sum1[N], sum2[N];
set<pair<int, int>> s1[N], s2[N];
vector<ll> ans;

void dfs0(int curr, int prev) {
  for(auto [next, w]:adj[curr]) if(next!=prev) par[next]=curr, pw[next]=w, st1[curr].push_back({w, next}), dfs0(next, curr);
  sort(st1[curr].rbegin(), st1[curr].rend());
  st2[curr]=st1[curr];
}

void dfs(int curr, int k, bool root=false) {
  dp[curr]=sum1[curr], ep[curr]=pw[curr]+sum2[curr];
  for(auto [next, w]:adj2[curr]) {
    dfs(next, k);
    dp[curr]+=dp[next], ep[curr]+=dp[next];
  }
  vector<pair<int, int>> in1, in2, out1, out2;
  for(auto [next, w]:adj2[curr]) {
    if(ep[next]-dp[next]<0 || s1[curr].size()<=deg[curr]-k)
      dp[curr]+=ep[next]-dp[next], in1.push_back({ep[next]-dp[next], next}), s1[curr].insert({ep[next]-dp[next], next});
    if(s1[curr].size()>deg[curr]-k && s1[curr].rbegin()->first>0)
      dp[curr]-=s1[curr].rbegin()->first, out1.push_back(*s1[curr].rbegin()), s1[curr].erase(prev(s1[curr].end()));
    if(ep[next]-dp[next]<0 || s2[curr].size()<=deg[curr]-k-1)
      ep[curr]+=ep[next]-dp[next], in2.push_back({ep[next]-dp[next], next}), s2[curr].insert({ep[next]-dp[next], next});
    if(s2[curr].size()>deg[curr]-k-1 && s2[curr].rbegin()->first>0)
      ep[curr]-=s2[curr].rbegin()->first, out2.push_back(*s2[curr].rbegin()), s2[curr].erase(prev(s2[curr].end()));
  }
  for(auto t:out1) s1[curr].insert(t);
  for(auto t:out2) s2[curr].insert(t);
  for(auto t:in1) s1[curr].erase(t);
  for(auto t:in2) s2[curr].erase(t);
  if(root) {
    if(curr!=1) ans[k]+=min(dp[curr], ep[curr]);
    else ans[k]+=dp[curr];
  }
}

vector<ll> minimum_closure_costs(int N, vector<int> U, vector<int> V, vector<int> W) {
  n=N;
  ans.resize(n);
  for(int i=0; i<n-1; i++) {
    U[i]++, V[i]++;
    adj[U[i]].push_back({V[i], W[i]}), adj[V[i]].push_back({U[i], W[i]});
    deg[U[i]]++, deg[V[i]]++;
  }
  for(int i=1; i<=n; i++) v[deg[i]].push_back(i);
  dfs0(1, 0);
  for(int k=n-1; k>=0; k--) {
    for(int j:v[k+1]) {
      adj2[par[j]].push_back({j, pw[j]});
      chk[j]=true, c.push_back(j);
      if(s1[par[j]].find({pw[j], j})!=s1[par[j]].end()) s1[par[j]].erase({pw[j], j}), sum1[par[j]]-=pw[j];
      if(s2[par[j]].find({pw[j], j})!=s2[par[j]].end()) s2[par[j]].erase({pw[j], j}), sum2[par[j]]-=pw[j];
    }
    for(int j:c) {
      while(s1[j].size()<deg[j]-k && !st1[j].empty()) {
        pair<int, int> tmp=st1[j].back(); st1[j].pop_back();
        if(chk[tmp.second]) continue;
        s1[j].insert(tmp), sum1[j]+=tmp.first;
      }
      while(s2[j].size()<deg[j]-k-1 && !st2[j].empty()) {
        pair<int, int> tmp=st2[j].back(); st2[j].pop_back();
        if(chk[tmp.second]) continue;
        s2[j].insert(tmp), sum2[j]+=tmp.first;
      }
    }
    for(int j:c) if(!chk[par[j]]) dfs(j, k, true);
  }
  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...