【洛谷P1084】疫情控制【二分+倍增+DFS+贪心】

本文详细解析了洛谷P1084题目的解题思路,包括倍增预处理关系和距离、二分答案、上提操作、查找空隙并记录以及贪心转移军队等关键步骤。通过二分搜索找到最小的最大时间,并利用深度优先搜索和图论策略优化解决方案。
摘要由CSDN通过智能技术生成

在这里插入图片描述
在这里插入图片描述
题目链接

分析

我A紫题了耶

这题乍一看好像不难啊就一个树形DP啊最多加上LCA处理一下啊。。。想来想去不太行。

feelings:有一点是确定的,就是我们要让军队尽量离根节点近一点,这样子就可以让这个军队控制的节点更多。而答案就是用时最大的那个军队的时间,而我们要让这个最大值最小,所以可能是二分答案。

这题思路线比较长,从这两个点入手,大致分几个步骤,我一个一个写出。

1、倍增预处理关系和距离

“让军队向上移动”的“上提”操作,就很容易想到用倍增优化。
f [ i ] [ j ] f[i][j] f[i][j] i i i 往上 2 j 2^j 2j 个节点,容易知道 f [ i ] [ 0 ] f[i][0] f[i][0] 就是 i i i 的父亲。设 d i s [ i ] [ j ] dis[i][j] dis[i][j] i i i i i i 往上 2 j 2^j 2j 个节点的距离。由类似求LCA前的预处理那样子,递推式显然,用个DFS遍历很容易求出。不会的先去学倍增LCA先。

void dfs(int x,int fx,int d)//倍增预处理 
{
   
	f[x][0]=fx;
	dis[x][0]=d;
	for(int i=1;i<=16;i++)
	{
   
		f[x][i]=f[f[x][i-1]][i-1];
		dis[x][i]=dis[x][i-1]+dis[f[x][i-1]][i-1];
	}
	for(int i=hd[x];i;i=e[i].next)
	{
   
		if(e[i].to!=fx) dfs(e[i].to,x,e[i].w);
	}
}
2、二分答案

直接二分一个时间,作为本次每支军队移动的最大时间,判断行不行,然后再次二分。这一部分很简单。

    int l=1,r=1000000;
	while(l<=r)
	{
   
		int mid=(l+r)>>1;
		if(pd(mid))
		{
   
			fff=1;//有解标记
			ans=mid;
			r=mid-1;
		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值