其他分享
首页 > 其他分享> > [APIO2021] 封闭道路 T3简要题解

[APIO2021] 封闭道路 T3简要题解

作者:互联网

感觉是整场考试中思维最简单的一题

考场写了\(O(n(\sqrt n + \log n))\),在luogu和uoj都是73,然后可能是因为没打.h,在CCF上爆零了,然后喜提铜牌

此处做法的复杂度是\(O(n\log n)\)的,在luogu上跑了440ms左右,还是挺快的

\(solution\)

for(int u = 0; u < N; ++u)
    for(auto v:E[u]){
        int o = max(deg[u],deg[v]);
        F[o] += w; 
    }
for(int i = 1; i < N; ++i)  F[i] += F[i-1];
void _delete(int u){
	for(auto now:E[u]){
		int v = now.fi,w = now.se;
		q[v].push(-w);Sw[v] += w;
	}
}
#include<bits/stdc++.h>
std::vector<long long> minimum_closure_costs(int N, std::vector<int> U,
                                             std::vector<int> V,
                                             std::vector<int> W);
using namespace std;
int read(){
	char c = getchar();
	int x = 0;
	while(c < '0' || c > '9')	c = getchar();
	while(c >= '0' && c <= '9')	x = x * 10 + c - 48,c = getchar();
	return x;
}
const int _ = 1e5 + 7;
int deg[_];int n;
#define ll long long
#define mp make_pair
#define fi first
#define se second
#define pb push_back 
typedef pair<int,int> pii;
vector<pii>E[_];
vector<ll>F;
vector<int>Ver;
bool cmp(pii a,pii b){
	return deg[a.fi] > deg[b.fi];
}
bool Cmp(int a,int b){
	return deg[a] < deg[b];
}
priority_queue<ll>q[_],bq[_];ll Sw[_];
int dfn[_],dfncnt;
void dfs1(int u,int fa){
	for(auto now:E[u]){
		int v = now.fi,w = now.se;
		if(v ^ fa){
			int o = max(deg[u],deg[v]);
			F[o] += w;
//			cout<<o<<" "<<w<<'\n'; 
			dfs1(v,u); 
		}
	}
}
ll dp1[_],dp2[_];
int st[_],top,bac[_],bcnt;
void _delete(int u){
	for(auto now:E[u]){
		int v = now.fi,w = now.se;
		q[v].push(-w);Sw[v] += w;
	}
}
void work(int u,int par,const int D){
	dfn[u] = D;
	dp1[u] = dp2[u] = 0;/*dp1[u]取D个,dp2[u]取D-1个*/
	for(auto now:E[u]){
		int v = now.fi;
		if(v ^ par){
//			cout<<u<<' '<<v<<"E"<<'\n';
			work(v,u,D);
		}
	}
	ll ans = 0;
	top = 0;
	for(auto now:E[u]){
		int v = now.fi,w = now.se;
		if(v ^ par){
			ans += dp1[v];
			if(w > (dp1[v] - dp2[v])){
				st[++top] = w - (dp1[v] - dp2[v]);
			}
		}
	}
	sort(st + 1,st + top + 1);
	reverse(st + 1,st + top + 1);
	ll S1 = 0,S2 = Sw[u];
	dp1[u] = Sw[u];dp2[u] = Sw[u];
//	if(D == 2)	cout<<Sw[u]<<'\n';
	assert(q[u].size() <= (unsigned int)D);
	if((int)q[u].size() == D)	dp2[u] += q[u].top();
//	cout<<u<<'\n';
	bcnt = 0;
//	cout<<u<<'\n';
	for(int i = 1; i <= min(top,D); ++i){/*选i个有用点,D-i个无用点*/
		S1 += st[i];
		if((int)q[u].size() > D - i){
			bac[++bcnt] = q[u].top();
			S2 += bac[bcnt];
			q[u].pop();
		}
		dp1[u] = max(dp1[u],S2 + S1);
		if(i == D)		continue;
		ll V = S2 + S1;if((int)q[u].size() >= D - i){
			V += q[u].top(); 
		}
		dp2[u] = max(dp2[u],V);
	}
//	cout<<u<<'\n';
	while(bcnt)	q[u].push(bac[bcnt]),bcnt--;
//	if(D == 2 && u == 1)	cout<<dp1[u]<<'\n';
	dp1[u] += ans;dp2[u] += ans;
	if(!par)	F[D] += dp1[u]; 
}
//vector<int> U;vector<int> V;vector<int> W;
vector<ll> minimum_closure_costs(int N,vector<int> U,vector<int> V,vector<int> W) {
	ll S = 0;
//	int N = read();
	n = N;
	/*for(int i = 0; i < N - 1; ++i){
		U.pb(0),V.pb(0),W.pb(0);
		U[i] = read(),V[i] = read(),W[i] = read();
	}*/
	for(int i = 1; i < N; ++i){
		int u = U[i-1] + 1,v = V[i-1] + 1,w = W[i-1];
//		u--,v--;
		deg[u]++,deg[v]++;
		S += w;
		E[u].pb(mp(v,w));E[v].pb(mp(u,w));
	}
	for(int i = 1; i <= N; ++i)	F.pb(0);
	for(int i = 1; i <= N; ++i)	Ver.pb(i);
	sort(Ver.begin(),Ver.end(),Cmp);Ver.pb(0);
	dfs1(1,0);
	for(int i = 1; i <= N; ++i)	sort(E[i].begin(),E[i].end(),cmp);
	for(int i = 1; i < N; ++i)	F[i] += F[i-1];
	int l = 0;
//	for(int i = 0; i < N; ++i)	cout<<Ver[i]<<' ';
//	cout<<'\n';
	for(int i = 1; i < N; ++i){
		while(l <= N && deg[Ver[l]] <= i){
			_delete(Ver[l]);
			l++;
		}
//		cout<<i<<' '<<l<<'\n';
		for(int ver = l; ver < N; ++ver){
			int u = Ver[ver];
			int k = E[u].size() - 1;
			while(k >= 0 && deg[E[u][k].fi] <= i){
				E[u].pop_back();
				k--;
			}
		}
//		puts("hxsb");
		for(int ver = l; ver < N; ++ver){
			int u = Ver[ver];
			while((int)q[u].size() > i){
				ll x = -q[u].top();
				q[u].pop();Sw[u] -= x;
				bq[u].push(x);
			}
			if((int)q[u].size() < i){
				if((int)bq[u].size()){
					ll x = bq[u].top();
					bq[u].pop();q[u].push(-x);Sw[u] += x;
				}
			}
			else{
				if((int)bq[u].size()) {
					ll x = bq[u].top();ll y = -q[u].top();
					if(x > y){
						q[u].pop();bq[u].pop();
						Sw[u] -= y;Sw[u] += x;
						q[u].push(-x);bq[u].push(y);
					}
				}
			}
		} 
		for(int ver = l; ver < N; ++ver){
			int u = Ver[ver];
			if(dfn[u] != i)	work(u,0,i);
		}
	}
	for(int i = 0; i < N; ++i)	F[i] = S - F[i];
//	for(int i = 0; i < N; ++i)	cout<<F[i]<<' ';
	return F;
}
/*int main(){
	freopen("data.in","r",stdin);
	freopen("data.out","w",stdout);
	minimum_closure_costs();
	return 0;
}*/

标签:dp1,int,题解,T3,++,vector,bq,APIO2021,deg
来源: https://www.cnblogs.com/y-dove/p/14824013.html