제출 #442589

#제출 시각아이디문제언어결과실행 시간메모리
442589Haruto810198도로 폐쇄 (APIO21_roads)C++17
17 / 100
219 ms51872 KiB
#include <bits/stdc++.h> using namespace std; #define int long long #define double long double #define FOR(i,l,r,d) for(int i=(l);i<=(r);i+=(d)) #define szof(x) ((int)(x).size()) #define vi vector<int> #define pii pair<int,int> #define F first #define S second #define pb push_back #define eb emplace_back #define mkp make_pair #define lsb(x) ((x)&(-(x)) const int INF = 2147483647; const int LNF = 4e18; const int MOD = 1000000007; const int mod = 998244353; const double eps = 1e-12; //#pragma GCC optimize("Ofast") //#pragma GCC optimize("unroll-loops") const int MAX = 100010; int n; vector<pii> edge[MAX]; /// original tree int deg[MAX]; /// degree of vertices pii par[MAX]; /// parent and childs of vectices, on the original tree vector<pii> ch[MAX]; vi induced[MAX]; /// vectices of each induced subgraph pii par_induced[MAX]; /// parent and childs of vectices, on the induced subgraph vector<pii> ch_induced[MAX]; int dep[MAX]; /// depth of vectices vi ord; /// order of dp int dp[MAX][2]; /// dp[vertex][is connnected to parent] int edge_cnt[MAX][11]; void edge_cnt_modify(int v, int pos, int val){ edge_cnt[v][pos] += val; } int edge_cnt_query(int v, int q){ int ret = 0; FOR(i, 1, 10, 1){ ret += i * min(q, edge_cnt[v][i]); q = max((int)0, q - edge_cnt[v][i]); } if(q > 0) return LNF; return ret; } /// calculate dep[], par[], ch[] void dfs(int v, pii pv, int cdep){ par[v] = pv; dep[v] = cdep; for(pii e : edge[v]){ int i = e.F; int w = e.S; if(i == pv.F) continue; ch[v].pb(e); dfs(i, mkp(v, w), cdep + 1); } } bool cmp_by_dep(int u, int v){ return (dep[u] < dep[v]); } /// solve for induced subgraph k int solve(int k){ for(int v : induced[k]){ par_induced[v] = mkp(v, 0); ch_induced[v].clear(); } /// update edges in induced subgraph k for(int v : induced[k]){ int u = par[v].F; int w = par[v].S; if(v!=u and deg[u]>k){ par_induced[v] = mkp(u, w); ch_induced[u].eb(v, w); edge_cnt_modify(v, w, -1); edge_cnt_modify(u, w, -1); } } /// dp order ord = induced[k]; sort(ord.begin(), ord.end(), cmp_by_dep); reverse(ord.begin(), ord.end()); /* cerr<<"solve("<<k<<") : "; for(int v : ord){ cerr<<v<<" "; } cerr<<endl; */ /// dp int ret = 0; for(int v : ord){ //cerr<<"dp["<<v<<"] : "<<endl; int ori_cost = 0; /// original cost if don't pick any child /// cost of picking each child vi cost_ch; for(pii e : ch_induced[v]){ int i = e.F; int w = e.S; /// pick : dp[i][1] + w /// not pick : dp[i][0] cost_ch.pb(dp[i][1] + w - dp[i][0]); ori_cost += dp[i][0]; } sort(cost_ch.begin(), cost_ch.end()); /* cerr<<"cost_ch : "; for(int i : cost_ch){ cerr<<i<<" "; } cerr<<endl; */ /// dp[v][0] dp[v][0] = LNF; int pick = deg[v] - k; /// n. of edges must pick to close int cost_ch_sum = 0; FOR(pick_ch, 0, pick, 1){ /// n. of edges picked from child int pick_ext = pick - pick_ch; /// n. of edges picked from extra edges dp[v][0] = min(dp[v][0], ori_cost + cost_ch_sum + edge_cnt_query(v, pick_ext)); if(pick_ch >= szof(cost_ch)) break; cost_ch_sum += cost_ch[pick_ch]; } assert(dp[v][0] < LNF); /// if v is a root in the induced graph : if(par_induced[v].F == v){ ret += dp[v][0]; continue; } /// dp[v][1] dp[v][1] = ori_cost + LNF; pick = deg[v] - k - 1; cost_ch_sum = 0; FOR(pick_ch, 0, pick, 1){ /// n. of edges picked from child int pick_ext = pick - pick_ch; /// n. of edges picked from extra edges dp[v][1] = min(dp[v][1], ori_cost + cost_ch_sum + edge_cnt_query(v, pick_ext)); if(pick_ch >= szof(cost_ch)) break; cost_ch_sum += cost_ch[pick_ch]; } assert(dp[v][1] < LNF); } /// recover edge_cnt for(int v : induced[k]){ int u = par[v].F; int w = par[v].S; if(v!=u and deg[u]>k){ edge_cnt_modify(v, w, 1); edge_cnt_modify(u, w, 1); } } /* cerr<<"dp : "<<endl; for(int v : induced[k]){ cerr<<"dp["<<v<<"][0] = "<<dp[v][0]<<"\t dp["<<v<<"][1] = "<<dp[v][1]<<endl; } cerr<<endl; */ return ret; } vi minimum_closure_costs(signed N, vector<signed> U, vector<signed> V, vector<signed> W){ int wsum = 0; /// input n = N; FOR(i, 0, n-2, 1){ int u = U[i], v = V[i], w = W[i]; edge[u].eb(v, w); edge[v].eb(u, w); deg[u]++; deg[v]++; edge_cnt_modify(u, w, 1); edge_cnt_modify(v, w, 1); wsum += w; } /// dfs dfs(0, mkp(0, 0), 0); /* cerr<<"par : "<<endl; FOR(i, 0, n-1, 1){ cerr<<"par["<<i<<"] = ("<<par[i].F<<", "<<par[i].S<<")"<<endl; } cerr<<endl; cerr<<"ch : "<<endl; FOR(i, 0, n-1, 1){ cerr<<"ch["<<i<<"] = "; for(pii e : ch[i]){ cerr<<"("<<e.F<<", "<<e.S<<") "; } cerr<<endl; } cerr<<endl; cerr<<"dep : "<<endl; FOR(i, 0, n-1, 1){ cerr<<"dep["<<i<<"] = "<<dep[i]<<endl; } cerr<<endl; */ /// induced subgraph FOR(i, 0, n-1, 1){ FOR(j, 0, deg[i]-1, 1){ induced[j].pb(i); } } /// solve for each induced subgraph vi res(n); res[0] = wsum; FOR(i, 1, n-1, 1){ res[i] = solve(i); } return res; } /* signed main(){ ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); //vi res = minimum_closure_costs(4, {0, 2, 0}, {1, 0, 3}, {5, 10, 5}); vi res = minimum_closure_costs(5, {0, 0, 0, 2}, {1, 2, 3, 4}, {1, 4, 3, 2}); cerr<<"res : "; for(int i : res){ cerr<<i<<" "; } cerr<<endl; 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...