luoguP1084 疫情控制(题解)(搜索+贪心)
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define il inline
#define rg register
#define ll long long
#define N 60000
#define inf 2147483647
using namespace std; int n,m,hd[N],cnt,u,v,w;
int c,idx[N];
int le,ri=;
int dis[N][],up[N][];
int ok[N],use[N],vis[N];
struct S{
int res,idx;
}ne[N],to[N];
struct T{
int nt,to,w;
}edge[N<<];
il void re(rg int &x);
void add(rg int fm,rg int to,rg int w);
void ST(rg int i,rg int fa);
int check(rg int lim);
int Dfs(rg int u,rg int fa);
int Cmp(const S &x,const S &y); int main()
{
re(n);
for(rg int i=;i<n;++i)
{
re(u),re(v),re(w);
add(u,v,w),add(v,u,w);
if(u==||v==)c++;
}
re(m);
if(m<c){cout<<-;return ;}
for(rg int i=;i<=m;++i)
re(idx[i]); ST(,);
for(rg int k=;k<=;++k)
{
for(rg int i=;i<=n;++i)
{
up[i][k]=up[up[i][k-]][k-];
dis[i][k]=dis[up[i][k-]][k-]+dis[i][k-];
}
}
while(le<ri)
{
rg int mid=((le+ri)>>);
if(check(mid))ri=mid;
else le=mid+;
}
cout<<le; return ;
} il void re(rg int &x)
{
rg int res=;rg int w=;char c=getchar();
while((c<''||c>'')&&c!='-')c=getchar();
if(c=='-')w=-,c=getchar();
while(c>=''&&c<='')res=(res<<)+(res<<)+c-'',c=getchar();
x=w*res;
}
void add(rg int fm,rg int to,rg int w)
{
edge[++cnt].nt=hd[fm];
edge[cnt].to=to;
edge[cnt].w=w;
hd[fm]=cnt;
}
void ST(rg int i,rg int fa)
{
up[i][]=fa;
for(rg int k=hd[i];k;k=edge[k].nt)
{
rg int qw=edge[k].to;
if(qw==fa)continue;
dis[qw][]=edge[k].w;
ST(qw,i);
}
}
int check(rg int lim){
memset(ok,,sizeof(ok));
memset(use,,sizeof(use));
memset(vis,,sizeof(vis));
rg int cnt1=,cnt2=;
rg int top=;
for(rg int i=;i<=m;++i){
rg int res=lim,u=idx[i];
for(rg int k=;k>=;--k){
if(up[u][k]&&up[u][k]!=&&res>=dis[u][k])
res-=dis[u][k],u=up[u][k];
}
if(up[u][]==&&res>dis[u][])
{
to[++cnt1].res=res-dis[u][];
to[cnt1].idx=u;
}
else ok[u]=;
}
Dfs(,);
for(rg int k=hd[];k;k=edge[k].nt){
rg int qw=edge[k].to;
if(!ok[qw]){
ne[++cnt2].res=dis[qw][];
ne[cnt2].idx=qw;
}
}
sort(to+,to+cnt1+,Cmp);
sort(ne+,ne+cnt2+,Cmp);
if(cnt1<cnt2)return ;
for(rg int i=;i<=cnt1;++i)
{
if(!vis[to[i].idx])
{
vis[to[i].idx]=;
continue;
}
while(vis[ne[top].idx])top++;
if(to[i].res>=ne[top].res)
{
vis[ne[top].idx]=,top++;
continue;
}
if(top>cnt2)break;
}
while(vis[ne[top].idx])top++;
if(top<=cnt2)return ;
return ;
}
int Dfs(rg int u,rg int fa)
{
rg int temp=,flag=;
for(rg int k=hd[u];k;k=edge[k].nt)
{
rg int qw=edge[k].to;
if(qw==fa)continue;
flag++,temp&=Dfs(qw,u);
}
if(!flag)temp=;
ok[u]=(ok[u]|temp);
if(ok[u]&&up[u][]==)
vis[u]=;
return ok[u];
}
int Cmp(const S &x,const S &y){return x.res<y.res;}
luoguP1084 疫情控制(题解)(搜索+贪心)的更多相关文章
- NOIP2012 疫情控制 题解(LuoguP1084)
NOIP2012 疫情控制 题解(LuoguP1084) 不难发现,如果一个点向上移动一定能控制更多的点,所以可以二分时间,判断是否可行. 但根节点不能不能控制,存在以当前时间可以走到根节点的点,可使 ...
- [CQOI2012]模拟工厂 题解(搜索+贪心)
[CQOI2012]模拟工厂 题解(搜索+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327574 链接题目地址:洛谷P3161 BZOJ P26 ...
- NOIP 2012 疫情控制(二分+贪心+倍增)
题解 二分时间 然后一个显然的事是一个军队向上爬的越高它控制的点越多 所以首先军队尽量往上爬. 当一个军队可以爬到根节点我们记录下它的剩余时间T和它到达根结点时经过的根节点的子节点son. 当一个军队 ...
- [NOIp2012]疫情控制 题解
好久没更,强迫自己写一篇. 神 tm 大预言家出的题 注意到如果 \(x\) 小时可以控制住疫情,则 \(\forall x'>x\) 必然也可以控制住疫情,显然答案具有单调性,可以二分答案. ...
- noip2012疫情控制 题解
题目大意 给出一棵n个节点的树,根是1,要在除根节点以外的点建立检查点,使得从每条根到叶子的路径上都至少存在一个检查点.检查点由军队来建立.初始军队的位置是给定的,移动军队走一条边需要花费这条边的权值 ...
- Luogu P1084 疫情控制 | 二分答案 贪心
题目链接 观察题目,答案明显具有单调性. 因为如果用$x$小时能够控制疫情,那么用$(x+1)$小时也一定能控制疫情. 由此想到二分答案,将问题转换为判断用$x$小时是否能控制疫情. 对于那些在$x$ ...
- NOIP2012 D2T3 疫情控制 题解
题面 这道题由于问最大值最小,所以很容易想到二分,但怎么验证并且如何实现是这道题的难点: 首先我们考虑,对于一个军队,尽可能的往根节点走(但一定不到)是最优的: 判断一个军队最远走到哪可以树上倍增来实 ...
- [NOIP2012]疫情控制 贪心 二分
题面:[NOIP2012]疫情控制 题解: 大体思路很好想,但是有个细节很难想QAQ 首先要求最大时间最小,这种一般都是二分,于是我们二分一个时间,得到一个log. 然后发现一个军队,越往上走肯定可以 ...
- Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)
Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...
随机推荐
- go web编程——session管理机制设计与实现
原生Go语言没有实现session管理机制,所以如果使用原生Go语言进行web编程,我们需要自己进行session管理机制的设计与实现,本文将就此进行详细介绍,并实现一个简单的session管理机制. ...
- 求解:为什么impala实现hive查询 可以使用ifnull()函数,不可以使用length() 函数
求大神解惑,找了很久都没有找到为什么??? hive支持length() 函数,不支持ifnull()函数??? impala实现hive查询 支持ifnull()函数,不支持length() 函数 ...
- JavaScript——正则匹配、正则提取、正则替换
正则匹配 // 匹配日期 var dateStr = '2015-10-10'; var reg = /^\d{4}-\d{1,2}-\d{1,2}$/ console.log(reg.test(da ...
- 2018-5-20-C#-BBcode-转-Markdown
title author date CreateTime categories C# BBcode 转 Markdown lindexi 2018-05-20 14:58:57 +0800 2018- ...
- zabbix入门之添加主机
添加主机的方法有两种:手动添加.自动发现 前提是:在被监控主机中安装zabbix-agent.zabbix-sender组件,并配置好启动服务. 手动添加: 自动发现: 这里等待1分钟左右即可发现主机 ...
- Git命令<转载 https://www.cnblogs.com/cspku/articles/Git_cmds.html>
查看.添加.提交.删除.找回,重置修改文件 git help <command> # 显示command的help git show # 显示某次提交的内容 git show $id gi ...
- python基础:9.深拷贝存储双字典
# 双层循环 temp = list() for i in range(1,100): item = {} itme["a"] = i for j in range(1,100): ...
- python输出转义字符
转义字符在字符串中不代表自己,比如\n代表回车,不代表\n字符,那我想输入转义字符本身呢? 答:在字符串前面加个r 如print(“aa\nbb”) 会输出aa bb 如print(r"aa ...
- Python中的"Special Method"
The first thing to know about special methods is that they are meant to be called by the Python inte ...
- python之字符串切分
在工作中,经常遇到字符串切分,尤其是操作linux命令,返回一段文本,如下面这种格式 Filesystem Size Used Avail Use% Mounted on /dev/vda1 40G ...