Luogu P1084 [NOIP2012]疫情控制
题目
首先我们二分一下答案。
然后我们用倍增让军队往上跳,最多先跳到根的子节点。
如果当前军队可以到达根节点,那么记录一下它的编号和它到达根节点后还可以走的时间。
并且我们记录根节点的叶子节点上到根节点后剩余时间最短的军队。
如果不可以到达根节点,那么在它跳到的节点设置检查点。
如果一个节点建立了检查点或者它的所有子树都设立了检查点,则说明以这个节点为根的子树已经被封死。记录根节点的所有子树中,未被封死的子树。
将我们已经记录好了的可以到根节点的军队按照剩余时间从大到小排序。
将未被封死的子树按照到子树到根节点的距离从大到小排序。
然后依次处理未被封死的子树要由哪支军队来管辖。
离根节点远的子树由剩余时间大的军队来管辖是没有问题的,不过更优的是由本来就在这棵子树上的军队来管辖。
所以我们先查看我们事先记录的(在子树中可以到达根节点,且到根节点后剩余时间最小的军队)是否被使用,如果被使用,再看当前没有被使用的军队里剩时间最大的可否到达这棵子树。
#include<bits/stdc++.h>
#define LL long long
#define pb push_back
#define P pair<int,int>
#define fir first
#define sec second
using namespace std;
namespace IO
{
char ibuf[(1<<21)+1],*iS,*iT;
char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
int read(){int x=0;char ch=Get();while(ch>57||ch<48)ch=Get();while(ch>=48&&ch<=57)x=x*10+(ch^48),ch=Get();return x;}
}
using namespace IO;
const int N=50007;
vector<P>E[N];
int pos[N],F[N][20],f[N],vis[N],used[N],r[N],n,m,cnt1,cnt2;
LL d[N][20];
struct node{int r,id;}a[N],b[N];
int operator<(node a,node b){return a.r>b.r;}
void dfs(int u,int fa,int dis)
{
F[u][0]=fa,d[u][0]=dis;
for(int i=1;i<=17;++i) F[u][i]=F[F[u][i-1]][i-1],d[u][i]=d[u][i-1]+d[F[u][i-1]][i-1];
for(P p:E[u]) if(p.fir^fa) dfs(p.fir,u,p.sec);
}
int checkd(int u,int fa)
{
int f1=1,f2=0;
if(vis[u]) return 1;
for(P p:E[u])
{
if(p.fir==fa) continue;
f2=1;
if(!checkd(p.fir,u))
{
f1=0;
if(u==1) b[++cnt2]=(node){p.sec,p.fir};
else return 0;
}
}
return f1&f2;
}
int check(int T)
{
cnt1=cnt2=0,memset(vis,0,sizeof vis),memset(f,0,sizeof f),memset(used,0,sizeof used);int i,j,u,s;
for(i=1;i<=m;++i)
{
for(u=pos[i],s=0,j=17;~j;--j) if(F[u][j]>1&&d[u][j]+s<=T) s+=d[u][j],u=F[u][j];
if(F[u][0]==1&&d[u][0]+s<=T)
{
a[++cnt1]=(node){T-s-d[u][0],i};
if(!f[u]||a[cnt1].r<r[u]) r[u]=a[cnt1].r,f[u]=i;
}
else vis[u]=1;
}
if(checkd(1,0)) return 1;
sort(a+1,a+1+cnt1),sort(b+1,b+1+cnt2),u=used[0]=1;
for(i=1;i<=cnt2;++i)
{
if(!used[f[b[i].id]]){used[f[b[i].id]]=1;continue;}
while(u<=cnt1&&(used[a[u].id]||a[u].r<b[i].r)) ++u;
if(u>cnt1) return 0;
used[a[u].id]=1;
}
return 1;
}
main()
{
n=read();int i,u,v,w,l=0,r=2e9,ans=-1,mid;
for(i=1;i<n;++i) u=read(),v=read(),w=read(),E[u].pb(P(v,w)),E[v].pb(P(u,w));
dfs(1,0,0),m=read();
for(i=1;i<=m;++i) pos[i]=read();
while(l<=r) check(mid=l+r>>1)? ans=mid,r=mid-1:l=mid+1;
return !printf("%d",ans);
}
Luogu P1084 [NOIP2012]疫情控制的更多相关文章
- Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)
Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...
- [NOIP2012]疫情控制 贪心 二分
题面:[NOIP2012]疫情控制 题解: 大体思路很好想,但是有个细节很难想QAQ 首先要求最大时间最小,这种一般都是二分,于是我们二分一个时间,得到一个log. 然后发现一个军队,越往上走肯定可以 ...
- NOIP2012 疫情控制 题解(LuoguP1084)
NOIP2012 疫情控制 题解(LuoguP1084) 不难发现,如果一个点向上移动一定能控制更多的点,所以可以二分时间,判断是否可行. 但根节点不能不能控制,存在以当前时间可以走到根节点的点,可使 ...
- noip2012 疫情控制
[问题描述] H国有n个城市,这n个城市用n-1条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点. H国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到边境城市(叶子 ...
- NOIP2012疫情控制(二分答案+倍增+贪心)
Description H国有n个城市,这n个城市用n-1条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点. H国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到边境 ...
- [NOIP2012]疫情控制(二分答案+倍增+贪心)
Description H国有n个城市,这n个城市用n-1条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点. H国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到边境 ...
- [NOIp2012]疫情控制 题解
好久没更,强迫自己写一篇. 神 tm 大预言家出的题 注意到如果 \(x\) 小时可以控制住疫情,则 \(\forall x'>x\) 必然也可以控制住疫情,显然答案具有单调性,可以二分答案. ...
- NOIP2012疫情控制(二分答案+树上贪心)
H 国有n个城市,这 n个城市用n-1条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点. H国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到边境城市(叶子节点所表示 ...
- noip2012疫情控制 题解
题目大意 给出一棵n个节点的树,根是1,要在除根节点以外的点建立检查点,使得从每条根到叶子的路径上都至少存在一个检查点.检查点由军队来建立.初始军队的位置是给定的,移动军队走一条边需要花费这条边的权值 ...
随机推荐
- Maven:mirror和repository
1 Repository(仓库) 1.1 Maven仓库主要有2种: remote repository:相当于公共的仓库,大家都能访问到,一般可以用URL的形式访问 local repository ...
- 【NOIP2014模拟11.3】蛋糕
题目 今天是Bessie的生日,他买了一个蛋糕和朋友们一起分享,蛋糕可以看成是一个R行C列的表格,共有R*C个格子,每个格子都有一个0至9的数字,表示该格子蛋糕拥有的巧克力.现在Bessie要把蛋糕横 ...
- NOIP2016提高A组五校联考1总结
第一题二分,在比赛上明明想到的方法,结果考虑的时候似乎漏了什么,被否决掉了. 只打了个水法,10分. 第二题,最长不上升子序列,原题,类似的题目做过两道,直接搞定. 第三题,一开始想了一种通过在树上打 ...
- 【leetcode】1200. Minimum Absolute Difference
题目如下: Given an array of distinct integers arr, find all pairs of elements with the minimum absolute ...
- git的clone和github的fork
git的clone是从github上下载下来,clone到项目里面,fork是在本地修改后再提交到github上,在github上用request来进行提交,经作者确认后可以合同到mast分支上
- pandas读取大文件时memoryerror的解决办法
再用pd.read_csv读取大文件时,如果文件太大,会出现memoryerror的问题. 解决办法一:pd.read_csv的参数中有一个chunksize参数,为其赋值后,返回一个可迭代对象Tex ...
- (67)c++后台开发
还记得自己在学校的时候,一直都比较注重的是:编程语言+数据结构与算法.没错,对于一个在校的计算机专业的学生,这是很重要的方面.但是,这往往不够,或许是因为毕业前一直没有进入企业实习,以至于自己在毕业之 ...
- JMS学习四(ActiveMQ消息过滤)
一.消息的选择器 不管是在消息发送端设置消息过期时间还是在接收端设置等待时间,都是对不满足的消息有过滤的作用,那消息选择器就是为过滤消息而生的下面来看看消息选择器: ActiveMQ提供了一种机制,使 ...
- 2018-2019-2 网络对抗技术 20165220 Exp 9 Web安全基础
2018-2019-2 网络对抗技术 20165220 Exp 9 Web安全基础 实验任务 本实践的目标理解常用网络攻击技术的基本原理,做不少于7个题目,共3.5分.包括(SQL,XSS,CSRF) ...
- 如何让css与js分离
在 webpack 我们如何让 css 与 js 分离: 我们需要安装插件:extract-text-webpack-plugin 1. 用:npm 下载插件 npm install extract- ...