NOIP2012 疫情控制 题解(LuoguP1084)

不难发现,如果一个点向上移动一定能控制更多的点,所以可以二分时间,判断是否可行。

但根节点不能不能控制,存在以当前时间可以走到根节点的点,可使向下走到深度为2的节点控制

其他点,此时又可以进行另一个贪心,优先选择走到根节点还能再走的时间小的去控制深度一到二之间边权较小的。

某大佬有更加详尽的讲解,参见这里

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; typedef long long ll;
const int MAXN=50000+5;
int anc[21][MAXN];
ll tab[21][MAXN];
struct Edge
{
int t,v,n;
}e[MAXN<<1];
int cnt,n,m,scnt;
int rsn[MAXN],siz[MAXN],army[MAXN],hd[MAXN],frm[MAXN];
bool cvef[MAXN],cover[MAXN];
typedef pair<int,int> pii;
pii a[MAXN],c[MAXN]; inline void build(int f,int t,int v)
{
e[++cnt]=(Edge){t,v,hd[f]};
hd[f]=cnt;
} void dfs1(int u)
{
if(anc[0][u]==1)
frm[u]=u;
else frm[u]=frm[anc[0][u]];
for(int i=hd[u];i;i=e[i].n)
{
int v=e[i].t;
if(v==anc[0][u])
continue;
++siz[u];
anc[0][v]=u;
tab[0][v]=e[i].v;
for(int i=1;anc[i-1][v];++i)
{
anc[i][v]=anc[i-1][anc[i-1][v]];
tab[i][v]=tab[i-1][v]+tab[i-1][anc[i-1][v]];
}
dfs1(v);
}
} void dfs2(int u)
{
cvef[u]=1;
if(siz[u]>1)
return;
for(int i=hd[u];i;i=e[i].n)
if(e[i].t!=anc[0][u])
dfs2(e[i].t);
}
void initrt()
{
for(int i=hd[1];i;i=e[i].n)
{
int v=e[i].t;
rsn[++scnt]=v;
dfs2(v);
}
} bool check(ll mid)
{
memset(cover,0,sizeof cover);
int cntc=0,cnta=0;
for(int i=1;i<=m;++i)
{
ll tmp=mid;
int pos=army[i];
for(int j=20;j>=0;--j)
{
if(anc[j][pos]&&tmp>=tab[j][pos])
{
tmp-=tab[j][pos];
pos=anc[j][pos];
}
}
if(pos!=1)
{
if(cvef[pos])
cover[frm[pos]]=1;
}
else
a[++cnta]=pii(tmp,frm[army[i]]);
}
for(int i=1;i<=scnt;++i)
{
if(!cover[rsn[i]])
c[++cntc]=pii(tab[0][rsn[i]],rsn[i]);
}
if(cntc>cnta)
return 0;
sort(a+1,a+cnta+1);
sort(c+1,c+cntc+1);
int j=1;
int t=cntc;
for(int i=1;i<=cnta;++i)
{
if(!cover[a[i].second])
cover[a[i].second]=1,--t;
else
{
while(j<=cntc&&cover[c[j].second])
++j;
if(a[i].first>=c[j].first)
cover[c[j].second]=1,++j,--t;
}
}
if(t>0)
return 0;
return 1;
} int main()
{
scanf("%d",&n);
int x,y,z;
ll l=0,r=0;
for(int i=1;i<n;++i)
{
scanf("%d%d%d",&x,&y,&z);
build(x,y,z);
build(y,x,z);
r+=z;
}
scanf("%d",&m);
for(int i=1;i<=m;++i)
scanf("%d",&army[i]);
dfs1(1);
initrt();
if(m<scnt)
{
puts("-1");
return 0;
}
while(r-l>1)
{
ll mid=l+r>>1;
if(check(mid))
r=mid;
else
l=mid;
}
printf("%lld",r);
return 0;
}

看来是只是贪心二分等基础算法我也不会QAQ

NOIP2012 疫情控制 题解(LuoguP1084)的更多相关文章

  1. [NOIp2012]疫情控制 题解

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

  2. noip2012疫情控制 题解

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

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

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

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

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

  5. luoguP1084 疫情控制(题解)(搜索+贪心)

    luoguP1084 疫情控制 题目 #include<iostream> #include<cstdlib> #include<cstdio> #include& ...

  6. NOIP2012 D2T3 疫情控制 题解

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

  7. noip2012 疫情控制

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

  8. NOIP2012疫情控制(二分答案+倍增+贪心)

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

  9. [NOIP2012]疫情控制(二分答案+倍增+贪心)

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

随机推荐

  1. vue 项目

    项目搭建 1. npm install -g @vue/cli 2.vue -h 3.vue create list-demo 4.yarn serve 运行项目 路由 1.yarn add vue- ...

  2. CF1237F Balanced Domino Placements

    题意 给定一个 \(h\) 行 \(w\) 列的方格图,上面已经放置了一些 \(1\times 2\) 的多米诺骨牌. 我们称一个放置多米诺骨牌的方案是好的,当且仅当任何两个多米诺骨牌不占用相同的行与 ...

  3. 咸鱼的ACM之路:动态规划(DP)学习记录

    按挑战程序设计竞赛介绍的顺序记录一遍学习DP的过程. 1. 01背包问题 问题如下: 有N个物品,每个物品(N[i])都有一定的体积(W[i]),和一定的价值(V[i]) 现在给定一个背包,背包的容量 ...

  4. 树莓派3B从装系统到安装RYU过程

    1.首先安装的是2019-09-26-raspbian-buster-lite系统 2.更换成国内源 更改apt源 sudo nano /etc/apt/sources.list(更改apt源) de ...

  5. (CPSCA's)CPOJC+VIJOS

    Coding Plus System Core Association 建立的Coding Plus Online Judge China 在Vijos上初步落脚,让我们拭目以待,等待暑假期间ACM1 ...

  6. Codeforces 1304F2 Animal Observation (hard version) 代码(dp滑动窗口线段树区间更新优化)

    https://codeforces.com/contest/1304/problem/F2 #include<bits/stdc++.h> using namespace std; ; ...

  7. Windows Server多用户同时远程登录

    因为工作需要,需要使用windwos作为一个远程登录跳板机,管理员对登录windwos机器再windwos的基础上连接别的机器,普通用户也可以连接windwos机器再连接别的机器,关于管理员普通用户连 ...

  8. CentOS 安装后的常用配置

    镜像配置 CentOS系统的镜像配置文件路径在 /etc/yum.repos.d/CentOS-Base.repo, 将镜像内容copy到 CentOS-Base.repo中 然后运行 yum mak ...

  9. C语言 goto

    C语言 goto 功能:无条件跳转.不推荐使用 案例 #include <stdio.h> int main() { // 函数跳转.循环跳转 // 创建标志位开始 // 无条件跳转到En ...

  10. 使用yum安装报错:[Errno 256] No more mirrors to try

    背景:我使用yum方式安装软件时,比如zabbix这种软件,我们在安装时一般都是直接到zabbix官网,按照官方的步骤进行安装,但是有一个问题,官方的服务器不在国内,时常会在安装时导致超时报错.此时解 ...