疫情控制(NOIP2012)庆祝2012满贯!٩(๑•◡-๑)۶ⒽⓤⒼ
丧病至极的D2T3啊!
好吧~
先放个传送门~
好吧,这道题呢。。
根据题意我们可以很明显的看出来
军队往上走的越多(在没到根节点之前),效益一定越大。。
所以可以分情况讨论:
对于无法走到根节点的军队,我们让他走到他能走到的离根节点最近的点
对于可以走到根节点,而且还有剩余时间的点,我们把它记到一个数组里【queen】。
由于第一层(也就是根节点)是无法停留的。
所以我们把能走到根节点的点全部扔到叶子节点还未被覆盖的第二层的点上。
由于结果的单调性,我们可以二分答案。
接下来是重点。
由于queen[]中的所有点都可以到任意一个第二层的点。
所以我们可以设想一个贪心。
把时间剩余最多的点给距离根节点最长的第二层的点。
如果出现找不到的情况,或者不满足的情况,
那么就往大二分,不然就往小二分;
最后的l就是答案啦!
接下来是小贴士:
1、如果你偷懒,不手写比较,而直接用multiset的话,en~你会TLE
2、如果不手打快排的话,你也很容易TLE
3、如果你不打快读的话,你很可能TLE
恩,我三种都没打~
但是过了~
怎么过的呢?~
我们先来看看题目
0<w<10^9..
好大。。
对不对。
但是如果用这个算法的话
时间复杂度为(nlog^2n)
那么是不是看上去不会炸?
可是二分的右端点怎么办?
有的人直接50000*10^9;
然后不写上面的优化全炸TLE
我机智的写了10^8.。
好吧,那是RP好,考场上这么写。。你就等死吧。
下面贴代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<cmath>
#include<algorithm>
using namespace std;
int n,num=,m,nownode;
int jd[];
int head[];
int leaf[];
int son[];
int sontree[];
bool visit[];
int queen[];
multiset<int> S;
multiset<int>::iterator it;
int dist[][];
int cnt[];
int fa[][];
int Min[];
struct duoyu{
int opt,timen;
}a[];
struct edge{
int next,to,value;
}g[];
void ins(int x1,int y1,int v1){
g[++num].next=head[x1];
head[x1]=num;
g[num].to=y1;
g[num].value=v1;
}
void dfs(int u)
{
sontree[u]=nownode;
visit[u]=true;
bool flag=;
for(int i=head[u];i;i=g[i].next){
int v=g[i].to;
if(!visit[v])
{
flag=false;
fa[v][]=u;
dist[v][]=g[i].value;
if(u==)nownode=v;
dfs(v);
}
}
leaf[u]=flag;
}
void findleaf(int x,int father){
if(cnt[x])return;
if(leaf[x])
{
son[nownode]=true;
return;
}
for(int i=head[x];i;i=g[i].next)
{
int v=g[i].to;
if(v!=father)
{
if(x==)nownode=v;
findleaf(v,x);
}
}
}
bool check(long long tme){
S.clear();
int arm=;
memset(son,,sizeof(son));
memset(cnt,,sizeof(cnt));
for(int i=;i<=m;i++)
{
long long len=tme;
int jundui=jd[i];
for(int j=;j>=;j--)
if(dist[jundui][j]<=len&&fa[jundui][j])
{
len-=dist[jundui][j];
jundui=fa[jundui][j];
}
if(jundui==)
{
a[++arm].opt=jd[i];
a[arm].timen=len;
}
else
cnt[jundui]++;
}
findleaf(,);
int tt=;
for(int i=;i<=n;i++)Min[i]=-;
for(int i=;i<=arm;i++)
{
int q=sontree[a[i].opt];
if(son[q]){
if(Min[q]==-||a[Min[q]].timen>a[i].timen)
Min[q]=i;
}
}
for(int i=;i<=n;i++)
if(son[i]&&Min[i]!=-&&a[Min[i]].timen<dist[i][])
a[Min[i]].timen=-;
else if(son[i]) queen[++tt]=dist[i][];
sort(queen+,queen+tt+);
for(int i=;i<=arm;i++)
{
if(a[i].timen!=-) S.insert(a[i].timen);
}
for(int i=tt;i>=;i--)
{
if(S.lower_bound(queen[i])==S.end()) return false;
it=S.lower_bound(queen[i]);
S.erase(it);
}
return true;
}
void addedge(int x1,int y1,int v1)
{
ins(x1,y1,v1);ins(y1,x1,v1);
}
int main(){
scanf("%d",&n);
for(int i=;i<n;i++)
{
int x,y,v;
scanf("%d%d%d",&x,&y,&v);
addedge(x,y,v);
}
dfs();
for(int j=;j<=;j++)
for(int i=;i<=n;i++)
{
fa[i][j]=fa[fa[i][j-]][j-];
dist[i][j]=dist[i][j-]+dist[fa[i][j-]][j-];
}
scanf("%d",&m);
for(int i=;i<=m;i++)scanf("%d",&jd[i]);
long long L=,R=;
long long ans=-;
while(L<=R){
long long mid=(L+R)>>;
if(check(mid)){R=mid-;ans= mid;}else L=mid+;
}
printf("%lld",ans);
return ;
}
没错!我最后改成了50万。。!过了!233
可是还是排在倒一(囧。。)
前排膜拜各路大神啊。。
听说拓补+倍增就100ms+..
蒟蒻滚粗。。(%%%zxyer)
疫情控制(NOIP2012)庆祝2012满贯!٩(๑•◡-๑)۶ⒽⓤⒼ的更多相关文章
- 疫情控制 [NOIP2012]
Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫 ...
- 洛谷P1084 疫情控制 [noip2012] 贪心+树论+二分答案 (还有个小bugQAQ
正解:贪心+倍增+二分答案 解题报告: 正好想做noip的题目然后又想落实学长之前讲的题?于是就找上了这题 其实之前做过,70,然后实在细节太多太复杂就不了了之,现在再看一遍感觉又一脸懵了... 从标 ...
- Codevs 1218 疫情控制 2012年NOIP全国联赛提高组
1218 疫情控制 2012年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description H 国有 n 个城市,这 ...
- 【NOIP2012】 疫情控制
[NOIP2012] 疫情控制 标签: 倍增 贪心 二分答案 NOIP Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...
- Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)
Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...
- [NOIP2012]疫情控制 贪心 二分
题面:[NOIP2012]疫情控制 题解: 大体思路很好想,但是有个细节很难想QAQ 首先要求最大时间最小,这种一般都是二分,于是我们二分一个时间,得到一个log. 然后发现一个军队,越往上走肯定可以 ...
- 疫情控制 2012年NOIP全国联赛提高组(二分答案+贪心)
P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...
- 洛谷P1084 [NOIP2012提高组Day2T3]疫情控制
P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...
- NOIP2012 疫情控制 题解(LuoguP1084)
NOIP2012 疫情控制 题解(LuoguP1084) 不难发现,如果一个点向上移动一定能控制更多的点,所以可以二分时间,判断是否可行. 但根节点不能不能控制,存在以当前时间可以走到根节点的点,可使 ...
随机推荐
- 为什么C++编译器不能支持对模板的分离式编译
首先,一个编译单元(translation unit)是指一个.cpp文件以及它所#include的所有.h文件,.h文件里的代码将会被扩展到包含它的.cpp文件里,然后编译器编译该.cpp文件为一个 ...
- 笔记-python-coroutine
笔记-python-coroutine 1. 协程 1.1. 协程的概念 协程,又称微线程,纤程.英文名Coroutine.协程是一种用户态的轻量级线程. 线程是系统级别的,它们是由操 ...
- 大话CNN经典模型:LeNet
近几年来,卷积神经网络(Convolutional Neural Networks,简称CNN)在图像识别中取得了非常成功的应用,成为深度学习的一大亮点.CNN发展至今,已经有很多变种,其中有 ...
- CodeForces 873F Forbidden Indices 后缀数组
忘了当时怎么做的了,先把代码贴上,保存一下后缀数组模板. #include <cstdio> #include <cstring> #include <algorithm ...
- Windows usb设备正在使用中
每次插上u盘之后,弹出的时候,总是提示正在使用中.后来我发现了技巧, 1.打开任务管理器 2.打开底部的 打开资源监视器 按钮 3.然后点击磁盘 4.再次弹出usb 就可以弹出了.
- jQuery的Ajax初识
1. 什么是Ajax? Ajax是“Asynchronous Javascript And XML(异步Javascript和XML)”的缩写, 是指一种创建交互式网页应用的网站开发技术. Ajax不 ...
- 亲手搭建一个基于Asp.Net WebApi的项目基础框架2
本篇目的:封装一些抽象类 1::封装日志相关类 2:封装一个Service操作类 3:封装缓存操作类 4:封装其他一些常用Helper 1.1在Framework项目里面建立好相关操作类文件夹,以便于 ...
- DOM事件里封装方法eventUtil
var eventUtil={ //添加句柄 addHandler:function (element,type,handler) { //element相当于btn2,type此时用的是click类 ...
- linux下vi的复制,黏贴,删除,撤销,跳转等命令-费元星
前言 在嵌入式linux开发中,进行需要修改一下配置文件之类的,必须使用vi,因此,熟悉 vi 的一些基本操作,有助于提高工作效率. 一,模式vi编辑器有3种模式:命令模式.输入模式.末行模式. ...
- Fiddler - 使用教程
1.断点调试,修改请求表单和响应数据 命令介绍: bpu在请求开始时中断,bpafter在响应到达时中断,bps在特定http状态码时中断,bpv/bpm在特定请求method时中断. bpu m.t ...