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 号城市是首都, 也是 ...
随机推荐
- .net core 使用RSA获取私钥证书并签名
RSA在.NET Core的改动 以前我们使用RSA加密主要是使用RSACryptoServiceProvider这个类,在.NET Core中也有这个类,但是这个类并不支持跨平台,所以如果你是用这个 ...
- Python-编码这趟浑水
最近听Alex讲到python编码,还特意用博客讲解,觉得问题严重了,于是翻看各种博客,先简单的对编码错误做一个总结,其他的后续慢慢补上,还得上班.还得学习.还得写博客?感觉有点吃不消了.各位大神不喜 ...
- 【LeetCode】深搜DFS(共85题)
[98]Validate Binary Search Tree [99]Recover Binary Search Tree [100]Same Tree [101]Symmetric Tree [1 ...
- fork/join并发编程
Fork & Join 的具体含义 Fork 一词的原始含义是吃饭用的叉子,也有分叉的意思.在Linux 平台中,函数 fork()用来创建子进程,使得系统进程可以多一个执行分支.在 Java ...
- Mysq修改引擎
[数据库]Mysql更改默认引擎为Innodb的步骤方法 前言 InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定. 基本的差别为:MyI ...
- Linux 给用户 赋某个文件夹操作的权限
https://my.oschina.net/cqyj/blog/1796047 在root用户登录的情况,赋予opt目录给liuhai这个用户权限 示例代码: # 将目录/opt 及其下面的所有文件 ...
- 【leetcode】714. Best Time to Buy and Sell Stock with Transaction Fee
题目如下: Your are given an array of integers prices, for which the i-th element is the price of a given ...
- Halo(十)
Spring Converter(转换器) @FunctionalInterface public interface Converter<S, T> { //一对一转换 @Nullabl ...
- 【RabbitMQ】Concurrency、Prefetch、exclusive
分布式消息中间件 RabbitMQ是用Erlang语言编写的分布式消息中间件,常常用在大型网站中作为消息队列来使用,主要目的是各个子系统之间的解耦和异步处理.消息中间件的基本模型是典型的生产者-消费者 ...
- php nl2br()函数 语法
php nl2br()函数 语法 作用:在字符串中的新行(\n)之前插入换行符dd马达 语法:nl2br(string,xhtml) 参数: 参数 描述 string 必须.规定要检查的字符串. xh ...