#include "roads.h"
#include <bits/stdc++.h>
using namespace std;
using ll = long long; using pii = pair<ll,ll>;
mt19937 gen;
const ll Nm = 1e5+5; ll N;
const ll K = 225; //sqrt(N)
ll ans[Nm];
vector<pii> adj[Nm];
vector<ll> fadj[Nm];
ll deg[Nm];
pii radj[Nm]; //{number, cost}
vector<ll> itpl; //inverse topological sort
ll dp0[Nm]; //no path up
ll dp1[Nm]; //path up
ll slvH(ll k) { //O(NlogN) independent of k
for (ll i=(N-1);i>=0;i--) {
ll x = itpl[i];
vector<ll> vaug; //augment vector
ll val0 = 0; //minimum value
for (ll y: fadj[x]) {
val0 += dp0[y];
vaug.push_back(dp1[y]-dp0[y]);
}
sort(vaug.begin(),vaug.end()); //can upgrade quicksort -> quickselect for true O(N)
ll NDEL = max(0LL,deg[x]-k);
dp0[x]=val0;
for (ll j=0;j<NDEL;j++) {
dp0[x]+=vaug[j];
}
NDEL = max(0LL,deg[x]-k-1);
dp1[x]=val0+radj[x].second;
for (ll j=0;j<NDEL;j++) {
dp1[x]+=vaug[j];
}
if (x!=0) {
dp0[x]=min(dp1[x],dp0[x]);
}
}
return dp0[0];
}
bool isH[Nm]; //is heavy? (aka deg>=K)
ll degL[Nm]; //light degree
vector<ll> aggL[Nm]; //light aggregates (choose x edges -> give cost)
vector<ll> elemL[Nm];
vector<pii> adjH[Nm];
pii radjH[Nm]; //heavy radj
vector<ll> fadjH[Nm]; //heavy fadj
vector<bool> foundH;
// ll gcalc(ll ndel, vector<ll> vaug, ll x) {
// vector<ll> vnew = vaug;
// for (ll y: elemL[x]) {
// vnew.push_back(y);
// }
// sort(vnew.begin(),vnew.end());
// ll vnewv = 0;
// for (ll i=0;i<ndel;i++) {
// vnewv += vnew[i];
// }
// return vnewv;
// }
ll gcalc(ll ndel, vector<ll> vaug, ll x) {
if (ndel==0) {return 0;}
if (elemL[x].size()==0 || ((vaug.size()>=ndel)&&(vaug[ndel-1]<=elemL[x][0]))) {
ll y = 0;
for (ll i=0;i<ndel;i++) {
y += vaug[i];
}
return y;
}
ll y=0; ll nfv=0; //total value, number from vaug
while (nfv<vaug.size()) {
if (nfv == ndel) {
return y;
}
auto A0 = upper_bound(elemL[x].begin(),elemL[x].end(),vaug[nfv]);
ll d0 = distance(elemL[x].begin(),A0); //# of elements <= vaug[nfv]
if ((d0+nfv+1)<=ndel) {
y += vaug[nfv];
nfv++;
} else {
return (y+aggL[x][ndel-nfv]);
}
}
return (aggL[x][ndel-nfv]+y);
}
ll slvL(ll k, vector<ll> rtpl /*reverse topological sort*/) { //O(SIZElogN) but need preprocessing -> only works for k>=K
for (ll i=(rtpl.size()-1);i>=0;i--) {
ll x = rtpl[i];
vector<ll> vaug;
ll val0 = 0;
for (ll y: fadjH[x]) {
val0 += dp0[y];
vaug.push_back(dp1[y]-dp0[y]);
}
sort(vaug.begin(),vaug.end());
dp0[x] = val0+gcalc(max(0LL,deg[x]-k),vaug,x);
dp1[x] = val0+radjH[x].second+gcalc(max(0LL,deg[x]-k-1),vaug,x);
if (i!=0) {
dp0[x]=min(dp1[x],dp0[x]);
}
}
return dp0[rtpl[0]];
}
vector<ll> minimum_closure_costs(int N1, vector<int> U, vector<int> V, vector<int> W) {
gen = mt19937((long long) new char);
N=N1;
for (ll i=0;i<N;i++) {
adj[i].clear();
fadj[i].clear();
}
itpl.clear();
ll sroad = 0;
for (ll i=0;i<(N-1);i++) {
adj[U[i]].push_back({V[i],W[i]});
adj[V[i]].push_back({U[i],W[i]});
sroad += W[i];
}
for (ll i=0;i<N;i++) {
deg[i]=adj[i].size();
}
queue<ll> q0;
q0.push(0); //root is 0
radj[0]={-1,-1};
while (!q0.empty()) {
ll x = q0.front(); q0.pop();
itpl.push_back(x);
for (pii p0: adj[x]) {
if (p0.first!=radj[x].first) {
fadj[x].push_back(p0.first);
radj[p0.first]={x,p0.second};
q0.push(p0.first);
}
}
}
for (ll i=0;i<N;i++) {
isH[i]=(deg[i]>=K);
radjH[i]={-1LL,-1LL};
}
for (ll i=0;i<N;i++) {
if (!isH[i]) {
continue;
}
vector<ll> iadjL; //values
for (pii p0: adj[i]) {
ll x = p0.first;
if (isH[x]) {
adjH[i].push_back(p0);
} else {
iadjL.push_back(p0.second);
}
}
degL[i]=iadjL.size();
sort(iadjL.begin(),iadjL.end());
elemL[i]=iadjL;
aggL[i].push_back(0);
ll cv = 0;
for (ll x: iadjL) {
cv += x;
aggL[i].push_back(cv);
}
}
foundH = vector<bool>(N,0);
vector<vector<ll>> itplsH; //heavy inverse topological sort
for (ll i=0;i<N;i++) {
if (!isH[i] || foundH[i]) {
continue;
}
queue<ll> q1;
q1.push(i);
vector<ll> vtc;
while (!q1.empty()) {
ll x = q1.front(); q1.pop();
foundH[x]=1;
vtc.push_back(x);
for (pii p0: adjH[x]) {
if (p0.first!=radjH[x].first) {
fadjH[x].push_back(p0.first);
radjH[p0.first]={x,p0.second};
q1.push(p0.first);
}
}
}
itplsH.push_back(vtc);
}
for (ll k=1;k<K;k++) {
ans[k]=slvH(k);
}
for (ll k=K;k<N;k++) {
ans[k]=0;
for (auto A0: itplsH) {
ans[k] += slvL(k,A0);
}
}
ans[0]=sroad;
vector<ll> ansF(N,0);
for (ll i=0;i<N;i++) {
ansF[i]=ans[i];
}
return ansF;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |