求助 TLE on test 6
查看原帖
求助 TLE on test 6
436107
Creeper_l楼主2024/8/13 16:44
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 5e5 + 10;
int n,head[MAXN],cnt,d[MAXN],dp[MAXN][3],sum[MAXN];
bool vis[MAXN];
struct Node {int u,v,w,nxt;}e[MAXN << 1];
inline void Add(int u,int v,int w) {
	e[++cnt] = {u,v,w,head[u]};
	head[u] = cnt;
}
queue <int> q,Q;
vector <int> v;
multiset <int> s[MAXN],S[MAXN]; 
typedef pair <int,int> pii;
vector <pii> g[MAXN];
bool cmp(pii x,pii y) {
	return d[x.first] > d[y.first];
}
map <pii,int> mp; 
inline void dfs(int u,int father,int deg,int root) {
	vis[u] = true; 
	int tot = 0;
	for(pii i : g[u]) {
		int now = i.first;
		if(d[now] <= deg) break;
		if(now == father || vis[now]) continue;
		dfs(now,u,deg,root); tot += dp[now][0];
		s[u].insert(dp[now][1] - dp[now][0]);
	}
	int p = d[u] - deg,f = 0;
	vector <int> m,M; m.clear(); M.clear();
	while(1) {
		int x = 1e18,y = 1e18;
		if(!s[u].empty()) x = *s[u].begin();
		if(!S[u].empty()) y = *S[u].begin();
		if(p <= 1 && min(x,y) > 0) break;
		if(x < y) {
			f += x;
			m.emplace_back(*s[u].begin());
			s[u].erase(s[u].begin());
		} else {
			f += y;
			M.emplace_back(*S[u].begin());
			S[u].erase(S[u].begin());
		} p--;
	}
	dp[u][1] = tot + mp[make_pair(u,father)] + f;
	if(deg >= 1 || u == root) {
		while(1) {
			int x = 1e18,y = 1e18;
			if(!s[u].empty()) x = *s[u].begin();
			if(!S[u].empty()) y = *S[u].begin();
			if(p <= 0 && min(x,y) > 0) break;
			if(x < y) {
				f += x;
				m.emplace_back(*s[u].begin());
				s[u].erase(s[u].begin());
			} else {
				f += y;
				M.emplace_back(*S[u].begin());
				S[u].erase(S[u].begin());
			} p--;
		}	
		dp[u][0] = tot + f;	
	} else dp[u][0] = 1e18;
//	cout << "u = " << u << " dp = " << dp[u][0] << " " << dp[u][1] << endl;
	for(auto i : M) S[u].insert(i);
}
signed main() {
	memset(head,-1,sizeof head);
	cin >> n;
	for(int i = 1,x,y,z;i < n;i++) {
		cin >> x >> y >> z;
		Add(x,y,z),Add(y,x,z);
		d[x]++,d[y]++;
		g[x].emplace_back(make_pair(y,z));
		g[y].emplace_back(make_pair(x,z));
		mp[make_pair(x,y)] = mp[make_pair(y,x)] = z;
	}
	for(int i = 1;i <= n;i++) 
		sort(g[i].begin(),g[i].end(),cmp);
	for(int i = 1;i <= n;i++) q.push(i);
	for(int i = 0;i < n;i++) {
		v.clear();
		while(!Q.empty()) Q.pop();
		while(!q.empty()) {
			if(d[q.front()] > i) v.emplace_back(q.front());
			else Q.push(q.front());
			q.pop(); 
		}
		for(int j : v) q.push(j);
		while(!Q.empty()) {
		 	int u = Q.front(); Q.pop();
		 	for(int i = head[u]; ~ i;i = e[i].nxt) {
		 		int now = e[i].v;
		 		S[now].insert(e[i].w);
		 		sum[now] += e[i].w;
			}
		}
		for(int j : v) {
			vis[j] = false;
			s[j].clear();
		}
		int ans = 0;
		for(int j : v) 
			if(!vis[j]) dfs(j,0,i,j),ans += dp[j][0];
		cout << ans << " ";
	}
	return 0;
}
/*
5
2 1 5
3 2 4
4 3 2
5 4 4
*/

不知道是常数写大了还是细节写挂写成了 O(n2)O(n^2)。本地测随机极限数据大概 2.3s。

2024/8/13 16:44
加载中...