P3574 [POI2014]FAR-FarmCraft 树上DP

题意:

给定一棵大小为 n n n树,走过每条边需要花费 1 1 1时间,安装软件又需要花费 c i c_i ci时间,需要遍历整棵树并回到起点,想让所有点中到达时间+安装时间的最大值最小,问这个值是多少

范围&性质: 1 ≤ n ≤ 5 × 1 0 5 , 1 ≤ c i ≤ 1 0 9 1\le n\le 5\times10^5,1\le c_i\le 10^9 1n5×105,1ci109

分析:

我们对于节点 u u u的儿子,按照最优方案下安装时间排序,我们二分一个最优时间,对于这些点我们从大往小的加入队列中,若当前的点无法直接插入到队列末尾,那就将他插入到最后一个元素的前面,这样能保证他影响到的点最少,要注意最后将 1 1 1点得到的方案,和 c 1 + ( n − 1 ) ∗ 2 c_1+(n-1)*2 c1+(n1)2取一次 m a x max max

代码:

#include<bits/stdc++.h>

using namespace std;

namespace zzc
{
	const int maxn = 5e5+5;
	const long long inf = 1e15+5; 
	long long f[maxn],head[maxn],siz[maxn],c[maxn];
    int n,cnt=0,tot;
	
	struct edge
	{
		int to,nxt;
	}e[maxn<<1];
	
	struct node
	{
		int f,t;
		bool operator<(const node &b)const
		{
			return f>b.f;
		}
	}p[maxn]; 
	
	void add(int u,int v)
	{
		e[++cnt].to=v;
		e[cnt].nxt=head[u];
		head[u]=cnt;
	}
	
	bool check(long long x)
	{
		int i,ed=0;
		long long last=0;
		for(int i=1;i<=tot;i++)
		{
			if(last+p[i].f<=x) last+=p[i].t,ed=i;
			else if(last-p[ed].t+p[i].t+p[ed].f>x) return false;
			else last+=p[i].t;
		}
		return true;
	}
	
	void dfs(int u,int fa)
	{
		siz[u]=1;
		for(int i=head[u];i;i=e[i].nxt)
		{
			int v=e[i].to;
			if(v==fa) continue;
			dfs(v,u);
			siz[u]+=siz[v];
		}
		tot=0;
		for(int i=head[u];i;i=e[i].nxt)
		{
			int v=e[i].to;
			if(v==fa) continue;
			p[++tot].f=f[v];
			p[tot].t=siz[v]*2ll;
		}
		sort(p+1,p+tot+1);
		long long l=p[1].f,r=inf,mid;
		while(l<r)
		{
			mid=(l+r)>>1;
			if(check(mid)) r=mid;
			else l=mid+1;
		}
		if(fa) f[u]=c[u];
		else f[u]=c[u]+((n-1)<<1);
		if(tot&&f[u]<l+1) f[u]=l+1;
	}
	
	void work()
	{
		int a,b;
		scanf("%d",&n);
		for(int i=1;i<=n;i++) scanf("%lld",&c[i]);
		for(int i=1;i<n;i++)
		{
			scanf("%d%d",&a,&b);
			add(a,b);add(b,a);
		}
		dfs(1,0);
		printf("%lld\n",f[1]);
	}
	
}

int main()
{
	zzc::work();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值