超时QAQ
查看原帖
超时QAQ
227824
JK_LOVER楼主2020/9/3 16:02
#include<bits/stdc++.h>
using namespace std;
const int N = 550005;
#define LL long long
LL ans,sum[N],f[N][2];
#define P pair<LL,LL>
vector<P> G[N<<1]; 
P d[N];
multiset<LL> H[N];
#define It multiset<LL>::iterator 
void insert(int x,LL val) {
	H[x].insert(val);
}
void erase(LL x,LL val) {
	It it = H[x].lower_bound(val);H[x].erase(it);
}
bool vis[N];
LL Max,du[N],n;
void die(LL x) {
	for(LL i = 0;i < G[x].size();i++) {
		LL y = G[x][i].second;
		if(du[y] <= Max) break;
		insert(y,G[x][i].first);sum[y] += G[x][i].first;
	}
}
bool cmp(P a,P b){
	return du[a.second] > du[b.second];
}
vector<LL> ins,del;
void dfs(int x,int fa) {
	vis[x] = 1;
	LL m = du[x] - Max;
	while(H[x].size() && H[x].size() > m) {
		It it = H[x].end();--it;sum[x]-= *it;H[x].erase(it);
	} 
	for(LL i = 0;i < G[x].size();i++) {
		LL y = G[x][i].second;
		if(y == fa) continue;
		if(du[y] <= Max) break;
		dfs(y,x); 
	}
	ins.clear();del.clear();
	LL Ans = 0;
	for(int i = 0;i < G[x].size();i++) {
		int y = G[x][i].second;
		if(y == fa) continue;
		if(du[y] <= Max) break;
		LL val = f[y][1] + G[x][i].first - f[y][0];
		if(val <= 0) {Ans += f[y][1] + G[x][i].first;m--;continue;}
		insert(x,val);del.push_back(val);
		Ans += f[y][0];sum[x] +=val;
	}
	while(H[x].size() && H[x].size() > m) {
		It it = H[x].end();--it;
		sum[x] -= *it,ins.push_back(*it),H[x].erase(it);
	} 
	f[x][0] = Ans + sum[x];
	while(H[x].size() && H[x].size() > m-1) {
		It it = H[x].end();--it;
		sum[x] -= *it,ins.push_back(*it),H[x].erase(it);
	} 
	f[x][1] = Ans + sum[x];
	for(LL i = 0;i < ins.size();i++) insert(x,ins[i]),sum[x] += ins[i];
	for(LL i = 0;i < del.size();i++) erase(x,del[i]),sum[x] -= del[i];
}
int main() {
	scanf("%lld",&n);	
	for(LL i = 1,a,b,c;i < n;i++) {
		scanf("%lld%lld%lld",&a,&b,&c);ans += c;
		G[a].push_back(P(c,b));
		G[b].push_back(P(c,a));
		du[a]++;du[b]++;
	}
	for(int i = 1;i <= n;i++) {
		d[i] = P(du[i],i);
		sort(G[i].begin(),G[i].end(),cmp);
	}
	sort(d+1,d+1+n);
	printf("%lld ",ans);
	LL pos = 1;
	for(Max = 1;Max < n;Max++) {
		while(pos <= n && d[pos].first <= Max) die(d[pos].second),++pos;
		ans = 0;memset(vis,0,sizeof(vis));
		for(int j = pos;j <= n;j++) {
			if(vis[d[j].second]) continue;
			dfs(d[j].second,0);
			ans += f[d[j].second][0];
		}
		printf("%lld ",ans);
	}
	printf("\n");
	return 0;
}


2020/9/3 16:02
加载中...