疫情控制(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) 不难发现,如果一个点向上移动一定能控制更多的点,所以可以二分时间,判断是否可行. 但根节点不能不能控制,存在以当前时间可以走到根节点的点,可使 ...
随机推荐
- python 初学函数
#len # s = '金老板小护士' # len(s) # def my_len(): #自定义函数 # i = 0 # for k in s: # i += 1 # print(i) # # le ...
- 陌生又熟悉的数据库之ID增加
当我们设计一张表时,通常为了保证记录的唯一性,会为表增加一个ID字段,生成记录时ID自动加一
- 笔记-爬虫-scrapy-srcapy-redis组件
笔记-爬虫-scrapy-srcapy-redis组件 1. 简介 scrapy是一个爬虫框架,但不支持分布式,scrapy-redis是为了更方便的实现scrapy分布式爬虫的组件. 可以 ...
- 3687: 简单题(bitset)
3687: 简单题 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 700 Solved: 319[Submit][Status][Discuss] ...
- Linux查看程序端口占用
使用命令: 1.ps -aux | grep 80 2.使用命令:netstat –apn 查看所有的进程和端口使用情况.
- printf("%d \n", -1 < sizeof(int) ) Implicit conversion
; printf( < sizeof(int) ); 结果输出: 0 在写程序时,经常对于比较很随意,特别是类型不同时,然而这带来的错误也是意想不到,却理所当然. 剖析: sizeof(int) ...
- Django基本使用
目录 1 安装 1.1 安装pip 1.2 安装django 2 创建项目 2.1 使用 管理工具 django-admin.py 来创建 PyLearn 项目: 2.2 启动服务 本文章以下所有列子 ...
- 《Cracking the Coding Interview》——第18章:难题——题目11
2014-04-29 04:30 题目:给定一个由‘0’或者‘1’构成的二维数组,找出一个四条边全部由‘1’构成的正方形(矩形中间可以有‘0’),使得矩形面积最大. 解法:用动态规划思想,记录二维数组 ...
- 【APUE】Chapter9 Process Relationships
这一章看的比较混乱,可能是因为例子少:再有就是,这一章就是一个铺垫的章节. 9.2 terminal logins 啥叫termnial? 我感觉书上的terminal指的更可能是一些物理设备(key ...
- Velocity 语法详解
Velocity是基于Java的模板引擎,它允许页面设计者引用Java中定义的方法.页面设计者和Java开发者能够同时使用MVC的模式开发网站,这样网页设计者能够把精力放在页面的设计上,程序员也可以把 ...