题目链接

观察题目,答案明显具有单调性。

因为如果用$x$小时能够控制疫情,那么用$(x+1)$小时也一定能控制疫情。

由此想到二分答案,将问题转换为判断用$x$小时是否能控制疫情。

对于那些在$x$小时内不能够走到根节点的子节点上的军队,让他们尽量往上走即可,走到哪里是哪里,这样显然不会更劣。

对于那些在$x$小时内能走到根节点的子节点上的军队,就让他们先走到根节点的子节点上。

然后搞搞贪心即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<fstream>
using namespace std;
struct edge
{
int last;
int end;
int weight;
}e[100005];
int n=0,m=0,ne=0;
int a[50005],note[50005],f[50005][20];
bool c[50005];
long long k1[50005],k2[50005],dis[50005];
vector<int> s[50005];
void NewEdge(int u,int v,int w)
{
ne++;
e[ne].last=note[u];
e[ne].end=v;
e[ne].weight=w;
note[u]=ne;
}
void dfs(int x,int fx)
{
for(int i=note[x];i;i=e[i].last)
if(e[i].end!=fx)
{
dis[e[i].end]=dis[x]+e[i].weight;
f[e[i].end][0]=x;
dfs(e[i].end,x);
}
}
void calc()
{
for(int j=1;j<=16;j++)
for(int i=1;i<=n;i++)
f[i][j]=f[f[i][j-1]][j-1];
}
bool dfss(int x,int fx)
{
if(c[x]) return false;
bool flag=false;
for(int i=note[x];i;i=e[i].last)
if(e[i].end!=fx)
{
flag=true;
if(dfss(e[i].end,x)) return true;
}
if(!flag) return true;
return false;
}
bool check(long long x)
{
for(int i=1;i<=n;i++)
c[i]=false,s[i].clear();
for(int i=1;i<=m;i++)
{
int y=a[i];
long long w=0;
for(int j=16;j>=0;j--)
if(f[y][j]>1&&w+dis[y]-dis[f[y][j]]<=x)
w+=dis[y]-dis[f[y][j]],y=f[y][j];
if(f[y][0]==1) s[y].push_back(a[i]);
c[y]=true;
}
int cnt1=0,cnt2=0;
for(int i=note[1];i;i=e[i].last)
{
bool h=c[e[i].end];
c[e[i].end]=false;
bool t=dfss(e[i].end,1);
c[e[i].end]=h;
int len=s[e[i].end].size();
for(int j=0;j<len;j++)
{
if(t&&dis[s[e[i].end][j]]+e[i].weight>x)
{t=false;continue;}
k1[++cnt1]=x-dis[s[e[i].end][j]];
}
if(t) k2[++cnt2]=e[i].weight;
}
sort(k1+1,k1+cnt1+1);
sort(k2+1,k2+cnt2+1);
for(int i=1,j=1;i<=cnt2;i++)
{
while(j<=cnt1&&k1[j]<k2[i]) j++;
if(j>cnt1) return false;
j++;
}
return true;
}
int main()
{
scanf("%d",&n);
long long hi=0;
for(int i=1;i<=n-1;i++)
{
int u=0,v=0,w=0;
scanf("%d%d%d",&u,&v,&w),hi+=w;
NewEdge(u,v,w);
NewEdge(v,u,w);
}
scanf("%d",&m);
for(int i=1;i<=m;i++) scanf("%d",&a[i]);
dfs(1,0),calc();
long long l=-1,r=hi;
while(l+1<r)
{
long long mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid;
}
if(!check(r)) printf("-1");
else printf("%lld",r);
return 0;
}

Luogu P1084

Luogu P1084 疫情控制 | 二分答案 贪心的更多相关文章

  1. LUOGU P1084 疫情控制(二分+贪心+树上倍增)

    传送门 解题思路 比较神的一道题.首先发现是最小值问题,并且具有单调性,所以要考虑二分答案.其次有一个性质是军队越靠上越优,所以我们要将所有的军队尽量向上提,这一过程我们用倍增实现.发现这时有两种军队 ...

  2. luogu P1084疫情控制 二分

    链接 loj luogu太水不要去了. 思路 二分. 每个军队在一定的时间内越往上越好. 注意一个军队可以跨过1去帮别的. 把能到1脚下的点都存下来特判. 有一种情况是这个子树内只有一个军队,但这个军 ...

  3. NOIP2012疫情控制(二分答案+树上贪心)

    H 国有n个城市,这 n个城市用n-1条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点. H国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到边境城市(叶子节点所表示 ...

  4. Luogu1084 NOIP2012D2T3 疫情控制 二分答案、搜索、贪心、倍增

    题目传送门 题意太长就不给了 发现答案具有单调性(额外的时间不会对答案造成影响),故考虑二分答案. 贪心地想,在二分了一个时间之后,军队尽量往上走更好.所以我们预处理倍增数组,在二分时间之后通过倍增看 ...

  5. 洛谷 P1084 疫情控制 —— 二分+码力

    题目:https://www.luogu.org/problemnew/show/P1084 5个月前曾经写过一次,某个上学日的深夜,精疲力竭后只有区区10分,从此没管... #include< ...

  6. luogu P1084 疫情控制

    传送门 首先,所有军队又要尽量往上走,这样才能尽可能的封锁更多的到叶子的路径 而随着时间的增加,能封锁的路径也就越来越多,所以可以二分最终的时间 然后对于每个时间,就让能走到根的军队走到根,记录到根上 ...

  7. luogu1084 [NOIp2012]疫情控制 (二分答案+倍增+dfs序)

    先二分出一个时间,把每个军队倍增往上跳到不能再跳 然后如果它能到1号点,就记下来它跳到1号点后剩余的时间:如果不能,就让它就地扎根,记一记它覆盖了哪些叶节点(我在这里用了dfs序+差分,其实直接dfs ...

  8. 疫情控制 2012年NOIP全国联赛提高组(二分答案+贪心)

    P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...

  9. BZOJ_2196_[Usaco2011 Mar]Brownie Slicing_二分答案+贪心

    BZOJ_2196_[Usaco2011 Mar]Brownie Slicing_二分答案+贪心 Description Bessie烘焙了一块巧克力蛋糕.这块蛋糕是由R*C(1 <= R,C ...

随机推荐

  1. CTFd+ubuntu service搭建等待更新

    CTFd是一款基于Apache2.0的协议的开源CTF平台,最新版本目前为1.20.该平台功能强大,基本上能够满足目前的CTF竞赛需求,同时,该平台提供了强大的插件功能,可以自己进行插件开发实现自己的 ...

  2. 机器学习——Adaboost

    1 Adaboost 的提出 1990年,Schapire最先构造出一种多项式级的算法,即最初的Boost算法; 1993年,Drunker和Schapire第一次将神经网络作为弱学习器,应用Boos ...

  3. C# 获取动态类中所有的字段

    /// <summary>        /// 动态类 获取字典集合        /// </summary>        /// <typeparam name= ...

  4. Jmeter系列(18)- 八大组件

    说明 取样器(Sampler):不与其他元件发⽣交互的作⽤的元件 逻辑控制器(Logic Controller):只对其⼦节点的sampler有效,⽽其他元件需要与sampler等元件交互 前置处理器 ...

  5. C++ 找零钱方法数

    * 动态规划法 #include "stdafx.h" #include <iostream> #include <vector> using std::v ...

  6. 一文让你彻底理解SQL连接查询

    表结构 内连接 笛卡尔积问题 普通内连接:inner join on 隐式内连接: 外连接 内连接与外连接查询的区别 内连接查询是查询两张表交集的数据,主外键关联的数据. 左连接查询是查询左表中的所有 ...

  7. CF1556E-Equilibrium【栈,树状数组】

    正题 题目连接:https://codeforces.com/contest/1556/problem/E 题目大意 两个长度为\(n\)的序列\(a,b\),\(q\)次询问一个区间\([l,r]\ ...

  8. Jmeter压测学习5---HTTP Cookie管理器

    我司项目暂时不需要,直接转载:https://www.cnblogs.com/yoyoketang/p/11963342.html 前言 web网站的请求大部分都有cookies,jmeter的HTT ...

  9. java 从零开始手写 RPC (04) -序列化

    序列化 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RPC (02)-netty4 实现客户端和服务端 java 从零开始手写 RPC (03) 如何实 ...

  10. 都 2021 年了,Serverless 能取代微服务吗?

    来源 | Serverless 公众号 编译 | OrangeJ 作者 | Mariliis Retter "Serverless 能取代微服务吗?" 这是知乎上 Serverle ...