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 疫情控制(题解)(搜索+贪心)的更多相关文章

  1. NOIP2012 疫情控制 题解(LuoguP1084)

    NOIP2012 疫情控制 题解(LuoguP1084) 不难发现,如果一个点向上移动一定能控制更多的点,所以可以二分时间,判断是否可行. 但根节点不能不能控制,存在以当前时间可以走到根节点的点,可使 ...

  2. [CQOI2012]模拟工厂 题解(搜索+贪心)

    [CQOI2012]模拟工厂 题解(搜索+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327574 链接题目地址:洛谷P3161 BZOJ P26 ...

  3. NOIP 2012 疫情控制(二分+贪心+倍增)

    题解 二分时间 然后一个显然的事是一个军队向上爬的越高它控制的点越多 所以首先军队尽量往上爬. 当一个军队可以爬到根节点我们记录下它的剩余时间T和它到达根结点时经过的根节点的子节点son. 当一个军队 ...

  4. [NOIp2012]疫情控制 题解

    好久没更,强迫自己写一篇. 神 tm 大预言家出的题 注意到如果 \(x\) 小时可以控制住疫情,则 \(\forall x'>x\) 必然也可以控制住疫情,显然答案具有单调性,可以二分答案. ...

  5. noip2012疫情控制 题解

    题目大意 给出一棵n个节点的树,根是1,要在除根节点以外的点建立检查点,使得从每条根到叶子的路径上都至少存在一个检查点.检查点由军队来建立.初始军队的位置是给定的,移动军队走一条边需要花费这条边的权值 ...

  6. Luogu P1084 疫情控制 | 二分答案 贪心

    题目链接 观察题目,答案明显具有单调性. 因为如果用$x$小时能够控制疫情,那么用$(x+1)$小时也一定能控制疫情. 由此想到二分答案,将问题转换为判断用$x$小时是否能控制疫情. 对于那些在$x$ ...

  7. NOIP2012 D2T3 疫情控制 题解

    题面 这道题由于问最大值最小,所以很容易想到二分,但怎么验证并且如何实现是这道题的难点: 首先我们考虑,对于一个军队,尽可能的往根节点走(但一定不到)是最优的: 判断一个军队最远走到哪可以树上倍增来实 ...

  8. [NOIP2012]疫情控制 贪心 二分

    题面:[NOIP2012]疫情控制 题解: 大体思路很好想,但是有个细节很难想QAQ 首先要求最大时间最小,这种一般都是二分,于是我们二分一个时间,得到一个log. 然后发现一个军队,越往上走肯定可以 ...

  9. Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)

    Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...

随机推荐

  1. navicat连接Oracle数据库提示错误 ORA-12514

    这个是服务名写错了,服务名的字段在Oracle安装路径里找 这个我的服务名,这好像是重装Oracle就会变我之前的事orcl,重装之后发现连接不上数据库了,就倔强着找到了它 备注:如果是连接远程Ora ...

  2. linux学习-系统监控工具

    系统监控工具 come from:https://blog.csdn.net/free050463/article/details/82842273top.free.vmstat.iostat.pma ...

  3. SELECT INTO - 从一个查询的结果中创建一个新表

    SYNOPSIS SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] * | expression [ AS output_name ] [ ...

  4. go语言从例子开始之Example36.互斥锁

    在前面的例子中,我们看到了如何使用原子操作来管理简单的计数器.对于更加复杂的情况,我们可以使用一个互斥锁来在 Go 协程间安全的访问数据. Example: package main import ( ...

  5. Android作业list

    作业1. 请在自己的电脑上完成Android的安装与配置,并完成Hello Android项目.上交自己与项目的合照,将照片传至QQ群中. ------------------------------ ...

  6. mysql授予权限

    grant show databases on *.* to 'asg'@'%'; grant select on *.* to 'asg'@'%'; grant show view on *.* t ...

  7. 【LeetCode】树(共94题)

    [94]Binary Tree Inorder Traversal [95]Unique Binary Search Trees II (2018年11月14日,算法群) 给了一个 n,返回结点是 1 ...

  8. shell编程程序实例

    1.计算器 #!/bin/bash #test #by authors hdc 2018 function add(){ #实现加法 c=$[ $a + $b ] #相加 echo $c } func ...

  9. poj 2104: K-th Number 【主席树】

    题目链接 学习了一下主席树,感觉具体算法思路不大好讲.. 大概是先建个空线段树,然后类似于递推,每一个都在前一个“历史版本”的基础上建立一个新的“历史版本”,每个历史版本只需占用树高个空间(好神奇!) ...

  10. Halo(八)

    安全模块 用户描述类 /** * 基本 Entity */ @Data @MappedSuperclass public class BaseEntity { /** Create time */ @ ...