因为若一个时间限制满足题意,则所有比它大的时间限制一定都满足题意,因此本题答案具有单调性,可以想到二分答案求解。

本题思路不是很难,但细节和代码实现比较复杂。

见牛人博客: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 提高组] 疫情控制 (二分答案、贪心)的更多相关文章

  1. [NOIP2012提高组]疫情控制

    题目:洛谷P1084.codevs1218.Vijos P1783. 题目大意:有一棵n个节点的,根为1的带权树和m支军队.每支军队可以在一个点上停下,那么从1开始就不能经过这个点了.现在有m支军队已 ...

  2. Luogu P1084 疫情控制 | 二分答案 贪心

    题目链接 观察题目,答案明显具有单调性. 因为如果用$x$小时能够控制疫情,那么用$(x+1)$小时也一定能控制疫情. 由此想到二分答案,将问题转换为判断用$x$小时是否能控制疫情. 对于那些在$x$ ...

  3. 洛谷P1084 [NOIP2012提高组Day2T3]疫情控制

    P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...

  4. NOIP2012疫情控制(二分答案+树上贪心)

    H 国有n个城市,这 n个城市用n-1条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点. H国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到边境城市(叶子节点所表示 ...

  5. Luogu1084 NOIP2012D2T3 疫情控制 二分答案、搜索、贪心、倍增

    题目传送门 题意太长就不给了 发现答案具有单调性(额外的时间不会对答案造成影响),故考虑二分答案. 贪心地想,在二分了一个时间之后,军队尽量往上走更好.所以我们预处理倍增数组,在二分时间之后通过倍增看 ...

  6. luogu1084 [NOIp2012]疫情控制 (二分答案+倍增+dfs序)

    先二分出一个时间,把每个军队倍增往上跳到不能再跳 然后如果它能到1号点,就记下来它跳到1号点后剩余的时间:如果不能,就让它就地扎根,记一记它覆盖了哪些叶节点(我在这里用了dfs序+差分,其实直接dfs ...

  7. 刷题总结——疫情控制(NOIP2012提高组)

    题目: 题目背景 NOIP2012 提高组 DAY2 试题. 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都 ...

  8. GZOJ 1361. 国王游戏【NOIP2012提高组DAY1】

    国王游戏[NOIP2012提高组DAY1] Time Limit:1000MS Memory Limit:128000K Description 国王游戏(game.cpp/c/pas) [问题描述] ...

  9. BZOJ_2196_[Usaco2011 Mar]Brownie Slicing_二分答案+贪心

    BZOJ_2196_[Usaco2011 Mar]Brownie Slicing_二分答案+贪心 Description Bessie烘焙了一块巧克力蛋糕.这块蛋糕是由R*C(1 <= R,C ...

随机推荐

  1. 向docker镜像中传递变量的两种方式

    测试用到的python文件: #!/usr/bin/env python3 #conding: utf-8 from http.server import HTTPServer, BaseHTTPRe ...

  2. Docker非root用户使用

    Docker 用户管理 安装Docker后docker相关命令都需要加上sudo才能执行,这里为特定用户添加下权限 Docker群组 不过一般安好docker后该群组已创建 sudo groupadd ...

  3. 利用Docker挂载Nginx-rtmp(服务器直播流分发)+FFmpeg(推流)+Vue.js结合Video.js(播放器流播放)来实现实时网络直播

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_75 众所周知,在视频直播领域,有不同的商家提供各种的商业解决方案,其中比较靠谱的服务商有阿里云直播,腾讯云直播,以及又拍云和网易云 ...

  4. 虚言妙诀终虚见,面试躬行是致知,Python技术面试策略与技巧实战记录

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_183 2021年,对于正在找工作的朋友来说,笼罩在新冠肺炎疫情之下,今年的就业季显得更加具有挑战性,更有意思的是,每当这个时候,各 ...

  5. OS模块中获取当前文件的绝对路径的相关方法

    os.path.realpath(__file__) 作用:获取当前执行py脚本的绝对路径(在当前工作目录下的绝对路径) __file__ : 表示当前文件的本身,一般值是当前文件的相对路径 例如: ...

  6. MySQL Test Run 测试框架介绍

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 介绍 MySQL Test Run 简称MTR,是MySQL官方提供的自动化测试框架,执行脚本在发布路径的mysql-te ...

  7. 【转载】一封面向社会,关于对近日来 CCF 不当行为之抗议的公开信

    原文链接:https://101001011.github.io/2022/06/11/zhi-ccf-de-yi-feng-gong-kai-xin/ 原文作者:CCA(CCA's Blog) 前天 ...

  8. Apache DolphinScheduler 使用文档(7/8):系统参数及自定义参数

    本文章经授权转载,原文链接: https://blog.csdn.net/MiaoSO/article/details/104770720 目录 7. 参数 7.1 系统参数 7.2 时间自定义参数 ...

  9. 介绍下Java内存区域(运行时数据区)

    介绍下Java内存区域(运行时数据区) Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域.JDK 1.8 和之前的版本略有不同. 下图是 JDK 1.8 对JV ...

  10. docker启动失败问题

    内核3.10,systemctl start docker 被阻塞,没有返回,查看状态为启动中. 某兄弟机器安装docker之后,发现systemctl start docker的时候阻塞,由于排查走 ...