P1084 [NOIP2012 提高组] 疫情控制 (二分答案、贪心)
因为若一个时间限制满足题意,则所有比它大的时间限制一定都满足题意,因此本题答案具有单调性,可以想到二分答案求解。
本题思路不是很难,但细节和代码实现比较复杂。
见牛人博客:https://www.luogu.com.cn/blog/TEoS/p1084-yi-qing-kong-zhi
1 #include<bits/stdc++.h>
2 typedef long long ll;
3 using namespace std;
4 const int N=6e4;
5 int n,m,t,tot,atot,btot,ctot;
6 int d[N],query[N],f[N][20];
7 int to[N<<1],edge[N<<1],nxt[N<<1],head[N];
8 bool ok,sta[N],need[N];
9 ll ans,tim[N],ned[N],dist[N][20];
10 pair<ll,int> h[N];
11 queue<int> q;
12 void add(int x,int y,int z){
13 nxt[++tot]=head[x];head[x]=tot;to[tot]=y;edge[tot]=z;
14 }
15
16 void bfs(){
17 q.push(1);d[1]=1;
18 while(q.size()){
19 int x=q.front();q.pop();
20 for(int i=head[x];i;i=nxt[i]){
21 int y=to[i];
22 if(d[y]) continue;
23 d[y]=d[x]+1;
24 f[y][0]=x;dist[y][0]=edge[i];
25 for(int j=1;j<=t;j++){
26 f[y][j]=f[f[y][j-1]][j-1];
27 dist[y][j]=dist[y][j-1]+dist[f[y][j-1]][j-1];
28 }
29 q.push(y);
30 }
31 }
32 }
33
34 void init(){
35 memset(sta,0,sizeof(sta));
36 memset(tim,0,sizeof(tim));
37 memset(ned,0,sizeof(ned));
38 memset(h,0,sizeof(h));
39 memset(need,0,sizeof(need));
40 atot=0,btot=0,ctot=0;
41 }
42
43 bool dfs(int x){
44 bool pson=0;
45 if(sta[x]) return 1;
46 for(int i=head[x];i;i=nxt[i]){
47 int y=to[i];
48 if(d[y]<d[x]) continue;
49 pson=1;
50 if(!dfs(y)) return 0;
51 }
52 if(!pson) return 0;
53 return 1;
54 }//如果是叶子结点,pson=0,那么该路径没有军队驻扎
55
56 bool ck(ll lim){
57 for(int i=1;i<=m;i++){//上移军队并处理闲置军队
58 ll x=query[i],cnt=0;
59 for(int j=t;j>=0;j--)
60 if(f[x][j]>1/*不能是根节点*/ && cnt+dist[x][j]<=lim){
61 cnt+=dist[x][j];
62 x=f[x][j];
63 }
64 if(f[x][0]==1 && cnt+dist[x][0]<=lim)
65 h[++ctot]=make_pair(lim-cnt-dist[x][0],x);
66 else sta[x]=1;
67 }
68 for(int i=head[1];i;i=nxt[i])
69 if(!dfs(to[i])) need[to[i]]=1;//dfs寻找路径未被驻扎的叶子节点
70 sort(h+1,h+ctot+1);//第一关键字排序
71 for(int i=1;i<=ctot;i++)
72 if(need[h[i].second] && h[i].first<dist[h[i].second][0])
73 need[h[i].second]=0;
74 else tim[++atot]=h[i].first;//对根节点的需要被驻扎的子节点进行初步处理
75 for(int i=head[1];i;i=nxt[i])
76 if(need[to[i]]) ned[++btot]=dist[to[i]][0];//找到仍需要被驻扎的节点并存储
77 if(atot<btot) return 0;//无解
78 sort(ned+1,ned+btot+1);
79 int i=1,j=1;
80 while(i<=btot && j<=atot)//双指针扫描
81 if(tim[j]>=ned[i]) i++,j++;
82 else j++;
83 if(i>btot) return 1;
84 return 0;
85 }
86
87 int main(){
88 cin>>n;ll l=0,r=0,mid;
89 t=log2(n)+1;
90 for(int i=1;i<n;i++){
91 int x,y,z;scanf("%d%d%d",&x,&y,&z);
92 add(x,y,z);add(y,x,z);r+=z;
93 }
94 bfs();//树上倍增预处理
95 cin>>m;for(int i=1;i<=m;i++) scanf("%d",&query[i]);//存每个军队
96 while(l<=r){//二分答案
97 init();mid=(l+r)>>1;
98 if(ck(mid)) r=mid-1,ans=mid,ok=1;
99 else l=mid+1;
100 }
101 if(!ok) cout<<-1<<endl;
102 else cout<<ans<<endl;
103 return 0;
104 }
P1084 [NOIP2012 提高组] 疫情控制 (二分答案、贪心)的更多相关文章
- [NOIP2012提高组]疫情控制
题目:洛谷P1084.codevs1218.Vijos P1783. 题目大意:有一棵n个节点的,根为1的带权树和m支军队.每支军队可以在一个点上停下,那么从1开始就不能经过这个点了.现在有m支军队已 ...
- Luogu P1084 疫情控制 | 二分答案 贪心
题目链接 观察题目,答案明显具有单调性. 因为如果用$x$小时能够控制疫情,那么用$(x+1)$小时也一定能控制疫情. 由此想到二分答案,将问题转换为判断用$x$小时是否能控制疫情. 对于那些在$x$ ...
- 洛谷P1084 [NOIP2012提高组Day2T3]疫情控制
P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...
- NOIP2012疫情控制(二分答案+树上贪心)
H 国有n个城市,这 n个城市用n-1条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点. H国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到边境城市(叶子节点所表示 ...
- Luogu1084 NOIP2012D2T3 疫情控制 二分答案、搜索、贪心、倍增
题目传送门 题意太长就不给了 发现答案具有单调性(额外的时间不会对答案造成影响),故考虑二分答案. 贪心地想,在二分了一个时间之后,军队尽量往上走更好.所以我们预处理倍增数组,在二分时间之后通过倍增看 ...
- luogu1084 [NOIp2012]疫情控制 (二分答案+倍增+dfs序)
先二分出一个时间,把每个军队倍增往上跳到不能再跳 然后如果它能到1号点,就记下来它跳到1号点后剩余的时间:如果不能,就让它就地扎根,记一记它覆盖了哪些叶节点(我在这里用了dfs序+差分,其实直接dfs ...
- 刷题总结——疫情控制(NOIP2012提高组)
题目: 题目背景 NOIP2012 提高组 DAY2 试题. 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都 ...
- GZOJ 1361. 国王游戏【NOIP2012提高组DAY1】
国王游戏[NOIP2012提高组DAY1] Time Limit:1000MS Memory Limit:128000K Description 国王游戏(game.cpp/c/pas) [问题描述] ...
- BZOJ_2196_[Usaco2011 Mar]Brownie Slicing_二分答案+贪心
BZOJ_2196_[Usaco2011 Mar]Brownie Slicing_二分答案+贪心 Description Bessie烘焙了一块巧克力蛋糕.这块蛋糕是由R*C(1 <= R,C ...
随机推荐
- DTS搭载全新自研内核,突破两地三中心架构的关键技术|腾讯云数据库
随着企业规模的扩大,对数据库可用性要求越来越高,更多企业采用两地三中心.异地多活的架构,以提高数据库的异常事件应对能力. 在数据库领域,我们常听的"两地三中心"."异地多 ...
- [apue] 文件中的空洞
空洞的概念 linux 上普通文件的大小与占用空间是两个概念,前者表示文件中数据的长度,后者表示数据占用的磁盘空间,通常后者大于前者,因为需要一些额外的空间用来记录文件的某些统计信息或附加信息.以及切 ...
- Border Theory
持续更新中!!!更个屁,无线停更! 前言: KMP 学傻了,看 skyh 说啥 border 树,跑来学 border 理论 洛谷云剪切板:https://www.luogu.com.cn/paste ...
- 羽夏看Linux内核——启动那些事
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ...
- 什么是hive的静态分区和动态分区,它们又有什么区别呢?hive动态分区详解
面试官问我,什么是hive的静态分区和动态分区,这题我会呀. 简述 分区是hive存放数据的一种方式,将列值作为目录来存放数据,就是一个分区,可以有多列. 这样查询时使用分区列进行过滤,只需根据列值直 ...
- HTTP的三次握手和四次挥手,以及DNS流程解析
首先模拟一个场景:你在浏览器输入自己想要访问的地址,浏览器发送请求到服务端,服务端进行响应,浏览器进行数据页面渲染,从而你得到自己想要访问地址的页面 总体流程图: DNS:可以认为域名与对应的ip转化 ...
- CDO如何盘点算法、推动算法业务增长
在数字经济时代,算法对企业业务增长至关重要,是企业进行数字化转型.构建竞争优势的关键.IT工程师或数据分析师可能会将算法描述为一组由数据操作形成的规则.而从业务价值方面考虑,算法是一种捕获商业机会.提 ...
- java-Collection,List简单使用与方法/(集合使用-中)
1.1集合只存放引用类型的元素并且集合存放的时元素的引用(地址)1.2新循环遍历集合 Collection c = new ArrayList(); c.add("one"); c ...
- Mysql 一主一从
1. 主从原理 1.1 主从介绍 所谓 mysql 主从就是建立两个完全一样的数据库,其中一个为主要使用的数据库,另一个为次要的数据库,一般在企业中,存放比较重要的数据的数据库服务器需要配置主从,这样 ...
- 2022CISCN-satool
2022CISCN-satool 打国赛的时候自己还并不了解LLVM PASS pwn,前几天正好学习了一下LLVM PASS pwn,于是就顺便来复现一下这道题目. 首先找到二进制文件的重写函数的主 ...