CF1399E1 Weights Division (easy version)

We first deal with how many contributions each edge will make to the cost. Then put each edge into the pile of roots according to the cost subtracted by one operation, from largest to smallest. Continue to take out the largest in the heap, subtract the smaller contribution, and then re-insert the element with the smaller contribution. Until the conditions are met.
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5; 
int T,n,s,u,v,w,ans,sum;
int size[N];
int cnt,head[N];
struct edge{
    
    int next,to,w,t;}e[N<<1];
struct node
{
    
    
	int t,w,v;
	inline bool operator < (const node &x) const
	{
    
    
		return x.v>v;
	}
};

inline void add(int u,int v,int w)
{
    
    
	cnt++;
	e[cnt].next=head[u];
	e[cnt].to=v;
	e[cnt].w=w;
	e[cnt].t=0;
	head[u]=cnt;
}

void dfs(int u,int fa)
{
    
    
	bool jay=true;
	for (register int i=head[u]; i; i=e[i].next)
	if (e[i].to!=fa)
	{
    
    
		jay=false;
		dfs(e[i].to,u);
		e[i].t=size[e[i].to];
		size[u]+=size[e[i].to];
	}
	if (jay) size[u]=1;
}

priority_queue<node>q;
signed main(){
    
    
	scanf("%lld",&T);
	while (T--)
	{
    
    
		scanf("%lld%lld",&n,&s);
		sum=0;
		while (q.size()) q.pop();	
		cnt=0;
		for (register int i=1; i<=n; ++i) head[i]=0;
		for (register int i=1; i<=n; ++i) size[i]=0;
		for (register int i=1; i<n; ++i)
		{
    
    
			scanf("%lld%lld%lld",&u,&v,&w);
			add(u,v,w);
			add(v,u,w);
		}
		dfs(1,0);
		for (register int i=1; i<=cnt; ++i)
		if (e[i].t)
		{
    
    
			sum+=e[i].t*e[i].w;
			int del=(e[i].w-e[i].w/2)*e[i].t;
			q.push((node){
    
    e[i].t,e[i].w/2,del});
		}
		ans=0;
		while (sum>s)
		{
    
    
			node u=q.top(); q.pop();	
			sum-=u.v;
			int del=(u.w-u.w/2)*u.t;
			q.push((node){
    
    u.t,u.w/2,del});
			ans++;
		}
		printf("%lld\n",ans);
	}
return 0;	
}

Guess you like

Origin blog.csdn.net/Dove_xyh/article/details/108434360