[NOIP2012][CODEVS1218]疫情控制(二分+倍增+贪心)

博客介绍了如何使用二分搜索、倍增算法和贪心策略解决疫情控制问题。通过判断在特定时间内军队能否控制疫情,优化军队路径,确保所有军队能到达目标位置。文章详细讲解了算法思路,并强调了实现过程中的细节处理和贪心策略的重要性。
摘要由CSDN通过智能技术生成

题目描述

传送门

题解

二分+判定,问题转化成了在mid的时间里能不能控制疫情。
关键是怎么check。

可以看出让所有的军队尽量向上走一定是最优的。可以倍增求出所有的军队在mid的时间里最多走到哪个点。
对于所有走不到根的军队,它们就只能停在那里了。对于所有走到根之后还有剩余时间的军队,可以继续走到根的别的儿子上,这些军队成为可以调动的军队。
枚举根的每一个儿子,如果这个儿子所代表的子树已经被控制了,即子树中所有走不到根的军队已经可以控制了这个子树,就不用管它。
如果它代表的子树没有被控制(注意这里不包括经过这个子树走到根的点),那么称这个点为需要调入的点。
所有可调动的军队都有一个剩余时间,所有需要调入的点都有一个需要时间(即根到儿子的边的权),将这两种点分别从小到大排序,贪心地分配,就可以达到目的。
需要注意的一点是,所有能走到根的军队一定是从根的某一个儿子走上来的,如果再让这个军队调去这个儿子的话,不能计算时间。具体做法是从小到大排序后,如果当前军队走上来的那个点没有被控制的话,就让这支军队去控制它走上来的那个点,否则的话,让它去控制它能控制的最小的点。
细节不好好想会出错的。

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define LL long long
#define N 50005
#define sz 16

int n,m,x,y,z,loc[N],cnt; LL Max,ans;
int tot,point[N],nxt[N*2],v[N*2]; LL c[N*2];
int f[N][sz+5]; LL s[N][sz+5];
bool vis[N],leaf,has_res[N];
struct hp
{
    int pt,lastp; LL ti,leftime;
    bool ctr;
}goal[N],res[N],save[N];

inline void addedge(int x,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值