Luogu1084 NOIP2012D2T3 疫情控制 二分答案、搜索、贪心、倍增
题意太长就不给了
发现答案具有单调性(额外的时间不会对答案造成影响),故考虑二分答案。
贪心地想,在二分了一个时间之后,军队尽量往上走更好。所以我们预处理倍增数组,在二分时间之后通过倍增看某一个军队能到达的深度最低的点。接着,我们发现有一些军队可以到达根节点,还有额外的时间去到别的子树上,而有一些子树没有被封闭完全。这个时候需要我们利用贪心思想来分配军队。
我们将能到达根节点的军队剩余的时间记录下来,并将军队由哪一棵子树而来记录下来,将其按照剩余时间从大到小排序。接着我们处理出没有完全封闭的子树数量,并将它们按照到根节点的边权大小从大到小排序。可以考虑到在分配某一棵子树的时候,一定是在满足条件的情况下选择剩余时间更少的更优。
而满足条件的军队有两种情况:①剩余时间大于等于该子树根节点到根的边权;②原来就由该棵子树来到根节点。对于①情况我们可以直接用指针处理,但是对于②并不是很好处理。我们可以如下处理:对剩余时间不满足条件的军队按照子树来源开个桶,每一次指针移动完毕之后,如果当前子树对应的桶中有军队,就直接拿出这个军队驻守这棵子树,并将这个桶中元素-1,在之后的指针移动中不算在可分配的军队内。
这神题码量真心很长
#include<bits/stdc++.h>
#define MAXN 50010
#define int long long
#define ld long double
using namespace std;
inline int read(){
;
;
char c = getchar();
while(!isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
struct Edge{
int end , upEd , time;
}Ed[MAXN << ];
struct L{
int ind , lTime;
bool operator < (L a){
return lTime > a.lTime;
}
}now[MAXN];
][] , head[MAXN] , army[MAXN] , N , M , cntEd , cntNow , cntQue;
bool vis[MAXN];
bool cmp(int a , int b){
][] > next[b][][];
}
inline void addEd(int a , int b , int c){
Ed[++cntEd].end = b;
Ed[cntEd].time = c;
Ed[cntEd].upEd = head[a];
head[a] = cntEd;
}
void dfs(int now){
; i <= ; i++){
next[now][i][] = next[next[now][i - ][]][i - ][];
next[now][i][] = next[now][i - ][] + next[next[now][i - ][]][i - ][];
}
for(int i = head[now] ; i ; i = Ed[i].upEd){
][]){
next[Ed[i].end][][] = now;
next[Ed[i].end][][] = Ed[i].time;
dfs(Ed[i].end);
}
}
}
inline int jump(int dir , int &k){
; i >= ; i--)
] <= k && next[dir][i][] != ){
k -= next[dir][i][];
dir = next[dir][i][];
}
return dir;
}
queue < int > q;
inline bool bfs(int dir){
while(!q.empty())
q.pop();
vis[dir] = ;
q.push(dir);
while(!q.empty()){
int t = q.front();
q.pop();
)
;
for(int i = head[t] ; i ; i = Ed[i].upEd)
if(!vis[Ed[i].end]){
q.push(Ed[i].end);
vis[Ed[i].end] = ;
}
}
;
}
inline bool check(int dir){
cntNow = cntQue = ;
memset(vis , , sizeof(vis));
memset(nowDir , , sizeof(nowDir));
vis[] = ;
; i <= M ; i++){
int k = dir , t = jump(army[i] , k);
][] <= k){
now[++cntNow].ind = t;
now[cntNow].lTime = k - next[t][][];
nowDir[t]++;
}
else
vis[t] = ;
}
] ; i ; i = Ed[i].upEd)
if(!vis[Ed[i].end] && bfs(Ed[i].end))
que[++cntQue] = Ed[i].end;
sort(que + , que + cntQue + , cmp);
sort(now + , now + cntNow + );
, cnt = ;
; i <= cntQue ; i++){
][]){
if(nowDir[now[dik].ind]){
nowDir[now[dik].ind]--;
cnt++;
}
dik++;
}
if(nowDir[que[i]])
nowDir[que[i]]--;
else
if(cnt)
cnt--;
else
;
}
;
}
main(){
next[][][] = ;
N = read();
; i < N ; i++){
int a = read() , b = read() , c = read();
addEd(a , b , c);
addEd(b , a , c);
}
dfs();
M = read();
; i <= M ; i++)
army[i] = read();
, R = 1e14 + ;
while(L < R){
;
if(check(mid))
R = mid;
else
L = mid + ;
}
)
cout << -;
else
cout << L;
;
}
Luogu1084 NOIP2012D2T3 疫情控制 二分答案、搜索、贪心、倍增的更多相关文章
- NOIP2012疫情控制(二分答案+树上贪心)
H 国有n个城市,这 n个城市用n-1条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点. H国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到边境城市(叶子节点所表示 ...
- luogu1084 [NOIp2012]疫情控制 (二分答案+倍增+dfs序)
先二分出一个时间,把每个军队倍增往上跳到不能再跳 然后如果它能到1号点,就记下来它跳到1号点后剩余的时间:如果不能,就让它就地扎根,记一记它覆盖了哪些叶节点(我在这里用了dfs序+差分,其实直接dfs ...
- Luogu P1084 疫情控制 | 二分答案 贪心
题目链接 观察题目,答案明显具有单调性. 因为如果用$x$小时能够控制疫情,那么用$(x+1)$小时也一定能控制疫情. 由此想到二分答案,将问题转换为判断用$x$小时是否能控制疫情. 对于那些在$x$ ...
- 洛谷P1084 疫情控制(NOIP2012)(二分答案,贪心,树形DP)
洛谷题目传送门 费了几个小时杠掉此题,如果不是那水水的数据的话,跟列队的难度真的是有得一比... 话说蒟蒻仔细翻了所有的题解,发现巨佬写的都是倍增,复杂度是\(O(n\log n\log nw)\)的 ...
- P1084 [NOIP2012 提高组] 疫情控制 (二分答案、贪心)
因为若一个时间限制满足题意,则所有比它大的时间限制一定都满足题意,因此本题答案具有单调性,可以想到二分答案求解. 本题思路不是很难,但细节和代码实现比较复杂. 见牛人博客:https://www.lu ...
- LUOGU P1084 疫情控制(二分+贪心+树上倍增)
传送门 解题思路 比较神的一道题.首先发现是最小值问题,并且具有单调性,所以要考虑二分答案.其次有一个性质是军队越靠上越优,所以我们要将所有的军队尽量向上提,这一过程我们用倍增实现.发现这时有两种军队 ...
- BZOJ 2525 Poi2011 Dynamite 二分答案+树形贪心
题目大意:给定一棵树,有一些点是关键点,要求选择不超过mm个点.使得全部关键点到近期的选择的点距离最大值最小 二分答案,问题转化为: 给定一棵树,有一些点是关键点,要求选择最少的点使得每一个关键点到选 ...
- bzoj1082: [SCOI2005]栅栏(二分答案搜索判断)
1082: [SCOI2005]栅栏 题目:传送门 题解: 是不是一开始在想DP?本蒟蒻也是qwq,结果很nice的错了ORZ 正解:二分+搜索 我们可以先把两种木材都进行排序,那么如果需要的最大木材 ...
- luogu5021 [NOIp2018]赛道修建 (二分答案+dp(贪心?))
首先二分一下答案,就变成了找长度>=m的 不相交的路径的个数 考虑到在一个子树中,只有一个点能出这个子树去和别的点搞 所以我这个子树里尽量自我满足是不会有坏处的 而且要在自我满足数最大的条件下, ...
随机推荐
- 转:drupal常用api
drupal常用api 最短的函数 // 语言字串,除了可以获取对应语言外,还可以设置字串变量.可以是!var, @var或 %var,%var就添加元素外层.@var会过滤HTML,!var会原 ...
- JMeter—逻辑控制器(六)
参考<全栈性能测试修炼宝典JMeter实战>第六章 JMeter 元件详解中第一节JMeter逻辑控制器 JMeter逻辑控制器可以对元件的执行逻辑进行控制,除仅一次控制器外,其他可以嵌套 ...
- 纯CSS选项卡
html: <!doctype html> <html> <head> <meta charset="utf-8"> <tit ...
- Linksys EA6500刷ddwrt成功记
网上刷Linksys EA6500的资料不多,然后又绕了好多个弯子,自己记录备忘. 首先EA6500有两个版本v1和v2,对应的固件不同. 区分方法: 1.v1的背后是两个颜色一样的usb2.0 2. ...
- Linux (Fedora 28) 如何查看 CPU 温度
机器突然负载有点高,查看CPU 温度的方法: 1.yum install lm_sensors; 2.sensors-detect 3.sensors 这些需要机器具备相应的设备,如果在虚拟机运行 ...
- Oracle 11g 发行版2的安装,PLSQL_Developer安装 , Oracle数据库安装失败,完全卸载,常用的命令
Oracle 11g 发行版2的安装 PLSQL_Developer安装 Oracle数据库安装失败,完全卸载oracle11g 常用的命令 Oracle 11g 发行版2的安装 1. 下载 下载地址 ...
- windows 实用技巧
以下内容版权归原作者所有!!!如果侵权,立即删除. 1.系统激活:https://mp.weixin.qq.com/s/Kl_iEeSSxSprblfSRZ6yEQ 2.百度云下载:https://w ...
- python 机器学习中模型评估和调参
在做数据处理时,需要用到不同的手法,如特征标准化,主成分分析,等等会重复用到某些参数,sklearn中提供了管道,可以一次性的解决该问题 先展示先通常的做法 import pandas as pd f ...
- openSUSE搭建OpenVPN
目录 openSUSE搭建OpenVPN 环境 安装openVPN服务端 安装easy-rsa工具 配置vars文件 创建服务端证书及key 创建客户端证书 疏理证书文件 服务端配置 启动openvp ...
- zabbix监控VMware6.7
1.登录VMwareweb页面 管理--高级配置启用:Config.HostAgent.plugins.solo.enableMob 2.测试(记住这个UUID) https://10.155.0.8 ...