Description

H国有n个城市,这n个城市用n-1条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点。 H国的首都爆发了一种危害性极高的传染病。当局为了控制疫情,不让疫情扩散到边境城市(叶子节点所表示的城市),决定动用军队在一些城市建立检查点,使得从首都到边境城市的每一条路径上都至少有一个检查点,边境城市也可以建立检查点。但特别要注意的是,首都是不能建立检查点的。 现在,在H国的一些城市中已经驻扎有军队,且一个城市可以驻扎多个军队。一支军队可以在有道路连接的城市间移动,并在除首都以外的任意一个城市建立检查点,且只能在一个城市建立检查点。一支军队经过一条道路从一个城市移动到另一个城市所需要的时间等于道路的长度(单位:小时)。 请问最少需要多少个小时才能控制疫情。注意:不同的军队可以同时移动。

\(Hint:2≤m≤n≤50,000,0 < w <10^9\)

Solution

可以发现,军队可以同时移动,那么就是求最大值最小,考虑二分答案,

接下来可以发现,军队越往上,控制的点越多,那么显然,军队应该尽量往上爬,

在树上向上爬,那就倍增吧(_

所以用贪心的思路,所有军队尽量往根节点爬,然后再考虑爬到一些没有军队的分支,

那么如果去支援分支,显然只要到根节点的某个子节点就能控制这个分支,

将向上能到达根节点的点存起来,用B数组储存,并且记录它是从根节点的哪个子节点上来的,因为可能不去支援其他点,就要返回到上一个点

而到不了根节点的点,保持在最高点为最优,将这个最高点标记,表示这个点被控制了,此时只有部分点被标记为控制的,

此时进行一个操作,对于一个非根节点的点,如果其子节点全被控制,那它也是被控制的,就这样从根节点遍历整棵树,记录所有被控制的点,用C数组储存

然后再考虑让可以到达根节点的点去支援没有被控制的根节点的子节点

接下来将没有被控制的根节点的子节点也存起来,然后将BC,2个数组按到根节点的距离排序

注意是从小到大!因为B数组要先考虑要不要返回上一个点,

然后判断是否C数组所有点都可以被控制即可

_)终于打完了,真的麻烦,细节挺多的,主要错误如下:

  1. 向上跳的时候,应先更新距离再更新点的编号
  2. 预处理倍增时,应从\(2^1\)开始算,因为\(2^0\)已经算过了
  3. !!!倍增最大可以到50000,但我看成5000,只开到\(2^{14}\),导致大数据挂

看来我倍增还是不熟练

Code

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define N 50010
using namespace std; struct info {
int to, nex, w;
} e[N * 2];
int n, m, tot, head[N * 2], ans, arm[N], l, r;
int _log, f[N][20], dis[N][20]; struct node {
int d, fr;
} b[N], c[N];
bool flag[N]; bool cmp(node a, node b) {return a.d < b.d;}
inline int read() {
int x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') {if (ch == '-')f = -1; ch = getchar();}
while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
return x * f;
} inline void add_edge(int u, int v, int w) {
e[++tot].to = v;
e[tot].nex = head[u];
head[u] = tot;
e[tot].w = w;
} void dfs(int u, int fa) {
for (int j = 1; j <= _log; ++j) {
f[u][j] = f[f[u][j - 1]][j - 1];
dis[u][j] = dis[u][j - 1] + dis[f[u][j - 1]][j - 1];
} for (int i = head[u]; i; i = e[i].nex) {
int v = e[i].to;
if (v == fa) continue;
f[v][0] = u;
dis[v][0] = e[i].w;
dfs(v, u);
}
} void color(int u, int fa) {
int p = 1, q = 0;
for (int i = head[u]; i; i = e[i].nex) {
int v = e[i].to;
if (v == fa) continue;
color(v, u);
p &= flag[v];
q = 1;
}
if (p && q && u != 1)
flag[u] = 1;
} bool check(int mid) {
memset(flag, 0, sizeof(flag));
int cnt = 0, top = 0;
for (int i = 1; i <= m; ++i) {
int u = arm[i], cos = 0;
for (int j = _log; j >= 0; --j)
if (f[u][j] && dis[u][j] + cos <= mid) {
cos += dis[u][j];
u = f[u][j];
}
if (u != 1) flag[u] = 1;
else {
b[++cnt].d = mid - cos;
u = arm[i];
for (int j = _log; j >= 0; j--)
if (f[u][j] > 1)
u = f[u][j];
b[cnt].fr = u;
}
}
color(1, 0);
for (int i = head[1]; i; i = e[i].nex) {
int v = e[i].to;
if (!flag[v]) {
c[++top].d = e[i].w;
c[top].fr = e[i].to;
}
}
sort(b + 1, b + cnt + 1, cmp);
sort(c + 1, c + top + 1, cmp);
int j = 1; c[top + 1].d = 1e9;
for (int i = 1; i <= cnt; ++i) {
if (!flag[b[i].fr]) flag[b[i].fr] = 1;
else if (b[i].d >= c[j].d) flag[c[j].fr] = 1;
while (flag[c[j].fr]) j++;
}
return j > top;
} inline void Init() {
n = read();
_log = log(n) / log(2);
for (int i = 1; i < n; ++i) {
int u = read(), v = read(), w = read();
r += w;
add_edge(u, v, w);
add_edge(v, u, w);
}
m = read();
for (int i = 1; i <= m; ++i)
arm[i] = read();
} int main() {
Init();
dfs(1, 0);
ans = -1;
while (l <= r) {
int mid = (l + r) >> 1;
if (check(mid))
ans = mid, r = mid - 1;
else l = mid + 1;
}
printf("%d\n", ans);
return 0;
}

[NOIP2012]疫情控制(二分答案+倍增+贪心)的更多相关文章

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

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

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

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

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

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

  4. 洛谷P1084 疫情控制(NOIP2012)(二分答案,贪心,树形DP)

    洛谷题目传送门 费了几个小时杠掉此题,如果不是那水水的数据的话,跟列队的难度真的是有得一比... 话说蒟蒻仔细翻了所有的题解,发现巨佬写的都是倍增,复杂度是\(O(n\log n\log nw)\)的 ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Ubuntu安装LAMP环境(PHP5.6) 以及下载安装phpmyadmin

    参考路径: http://blog.nciaer.com/?p=133 修改apache(2.4.18)的web路径时, 需要将 /etc/apache2/sites-available/000def ...

  2. xmanger图形化登陆远程服务器

    由于网上的资料比较杂,经过本人整理实际操作验证,保证ok  本人的服务器系统为centos5.8 下面的都是centos服务器上的操作,需要简单的配置下: win客户端使用xmanger软件:首先是服 ...

  3. prototype 以及 constructor 属性的理解

    1 为什么 xx.constructor.prototype 可以访问到当前对象的原型. 'str'.constructor.prototype      'str'.constructor 指向当前 ...

  4. Python开发环境Wing IDE如何使用调试功能

    在使用Wing IDE开始调试的时候,需要设置断点的行,读取GetItemCount函数的返回.这可以通过单击行并选择Break工具栏条目,或通过单击行左边的黑色边缘.断点应该以实心红圈的形式出现: ...

  5. Spring+Hibernateh使用小结

    由此我们可以看出,报出错误的地方主要是slf4j的jar包,而故障码中“Failed to load class ’org.slf4j.impl.StaticLoggerBinder‘”的意思则是“加 ...

  6. URL最大长度问题

    在http协议中,其实并没有对url长度作出限制,往往url的最大长度和用户浏览器和Web服务器有关,不一样的浏览器,能接受的最大长度往往是不一样的,当然,不一样的Web服务器能够处理的最大长度的UR ...

  7. LeetCode Number of 1 Bits 计算1的个数

    题意: 提供一个无符号32位整型uint32_t变量n,返回其二进制形式的1的个数. 思路: 考察二进制的特性,设有k个1,则复杂度为O(k).考虑将当前的数n和n-1做按位与,就会将n的最后一个1去 ...

  8. hihocoder 1093 SPFA算法

    题目链接:http://hihocoder.com/problemset/problem/1093 , 最短路的SPFA算法. 由于点的限制(10w),只能用邻接表.今天也学了一种邻接表的写法,感觉挺 ...

  9. 2018.1.30 PHP编程之验证码

    PHP编程之验证码 1.创建验证码函数 验证码函数输入通用函数,将函数放入global.func.php里. //创建一个随机码 for($ i=0;$i<4;$i++){ $_nmsg. = ...

  10. matlplotlib 为折线图填充渐变颜色

    概要   本篇记录绘图时填充颜色时的一些常用设置,主要用到了 imshow,fill 函数.   填充图实例   填充的效果图如下: 图 1:渐变色效果图 可根据下方给出的代码进行自定义. #!/us ...