Solution

二分答案, 尽量往上跳, 不能跳到根节点.

仍然能跳的拿出来.看剩下的点没有覆盖哪个?

贪心的分配一下.

Code

70

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N = 50005; int n, m; struct Edge {
int v, c; Edge* nxt;
Edge(int _, int __, Edge* ___) :
v(_), c(__), nxt(___) {}
} *head[N];
void AddEdge(int u, int v, int c) {
head[u] = new Edge(v, c, head[u]);
head[v] = new Edge(u, c, head[v]);
} int f[N][18], p[N]; long long dis[N][18]; void dfs(int u, int fa, long long distan) {
f[u][0] = fa, dis[u][0] = distan;
for (int i = 1; i <= 17; i += 1) {
f[u][i] = f[f[u][i - 1]][i - 1];
dis[u][i] = dis[u][i - 1] + dis[f[u][i - 1]][i - 1];
}
for (auto edge = head[u]; edge; edge = edge->nxt) {
if (edge->v != fa)
dfs(edge->v, u, edge->c);
}
}
struct node {
node() {}
long long rest; int id;
node(int _id, int _r) :
id(_id), rest(_r) {}
bool operator < (const node& o) const {
return rest < o.rest;
}
} a[N], b[N]; int vis[N], used[N], R[N];
long long Min[N];
int A, B; int Dfs(int u, int fa) {
int f1 = true, noleaf = false;
if (vis[u]) return true;
for (auto edge = head[u]; edge; edge = edge->nxt) {
if (edge->v == fa) continue;
noleaf = true;
if (not Dfs(edge->v, u)) {
f1 = 0;
if (u == 1)
b[B++] = node(edge->v, edge->c);
else return false;
}
}
if (not noleaf) return false;
return f1;
} int check(long long lim) {
int u, now;
long long num;
A = B = 0;
for (int i = 1; i <= n; i += 1) vis[i] = 0;
for (int i = 1; i <= n; i += 1) R[i] = 0;
for (int i = 1; i <= m; i += 1) used[i] = 0;
for (int i = 1; i <= m; i += 1) {
u = p[i], num = 0;
for (int j = 17; ~j; j -= 1)
if (f[u][j] > 1 and num + dis[u][j] <= lim)
num += dis[u][j], u = f[u][j];
if (f[u][0] == 1 and num + dis[u][0] <= lim) {
a[A++] = node(i, lim - num - dis[u][0]);
if (not R[u] or a[A].rest < Min[u])
Min[u] = a[A].rest, R[u] = i;
} else vis[u] = 1;
}
if (Dfs(1, 0)) return true;
sort(a, a + A);
sort(b, b + B);
now = 0, used[0] = 1;
for (int i = 0; i < B; i += 1) {
if (!used[R[b[i].id]]) {
used[R[b[i].id]] = 1; continue;
}
while (now < A and (used[a[now].id] or a[now].rest < b[i].rest)) now += 1;
if (now >= A) return false;
used[a[now].id] = true;
}
return 1;
} int main() {
scanf("%d", &n);
for (int i = 1, u, v, c; i < n; i += 1) {
scanf("%d%d%d", &u, &v, &c);
AddEdge(u, v, c);
}
dfs(1, 0, 0);
scanf("%d", &m);
int l = 0, r = 5e5, mid;
for (int i = 1; i <= m; i += 1) scanf("%d", &p[i]);
while (l <= r) {
mid = l + r >> 1;
if (check(mid)) r = mid - 1;
else l = mid + 1;
}
printf("%d\n", l);
return 0;
}

P1084 疫情控制的更多相关文章

  1. [NOIP2012] 提高组 洛谷P1084 疫情控制

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

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

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

  3. NOIP2012 洛谷P1084 疫情控制

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

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

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

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

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

  6. luogu P1084 疫情控制

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

  7. 洛谷P1084 疫情控制 [noip2012] 贪心+树论+二分答案 (还有个小bugQAQ

    正解:贪心+倍增+二分答案 解题报告: 正好想做noip的题目然后又想落实学长之前讲的题?于是就找上了这题 其实之前做过,70,然后实在细节太多太复杂就不了了之,现在再看一遍感觉又一脸懵了... 从标 ...

  8. 2018.09.26洛谷P1084 疫情控制(二分+倍增)

    传送门 好题啊. 题目要求的最大值最小,看到这里自然想到要二分答案. 关键在于怎么检验. 显然对于每个点向根走比向叶节点更优. 因此我们二分答案之后,用倍增将每个点都向上跳到跳不动为止. 这时我们ch ...

  9. luogu P1084疫情控制 二分

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

随机推荐

  1. 常州day3

    Task1 小 W 得到了一堆石子,要放在 N 条水平线与 M 条竖直线构成的网格的交点上.因为小 M 最喜欢矩形了, 小 W 希望知道用 K 个石子最多能找到多少四边平行于坐标轴的长方形,它的四个角 ...

  2. BZOJ3782 上学路线 【dp + Lucas + CRT】

    题目链接 BZOJ3782 题解 我们把终点也加入障碍点中,将点排序,令\(f[i]\)表示从\((0,0)\)出发,不经过其它障碍,直接到达\((x_i,y_i)\)的方案数 首先我们有个大致的方案 ...

  3. linux系统启动自动激活网卡的解决方法

    linux每次启动的时候网卡都需要激活才能上网,实在是很麻烦. 上网找了找资料,最后是这样解决的: #   vi   /etc/sysconfig/network-scripts/ifcfg-eth0 ...

  4. 谷哥的小弟学前端(02)——HTML常用标签(2)

    探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架 ...

  5. 【bzoj4811】由乃的OJ

    Portal --> bzoj4811 Solution  这题可以用树剖+线段树做也可以用LCT做,不过大体思路是一样的  (接下来先讲的是树剖+线段树的做法,再提LCT的做法) ​  首先位 ...

  6. NYOJ--69

    数的长度 原题链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=69 分析:先看看求n!的朴素算法,用大整数乘法来实现. #include< ...

  7. Swagger2 添加HTTP head参数,解决用户是token信息保留

    转:http://blog.csdn.net/u014044812/article/details/71473226 大家使用swagger往往会和JWT一起使用,而一般使用jwt会将token放在h ...

  8. CentOS6.6安装heartbeat配置资源切换操作笔记实现高可用(原创)

    参考资料:http://www.centoscn.com/CentosServer/cluster/2015/0605/5604.html   背景需求: 使用heartbeat来做HA集群,并且把n ...

  9. discuz uc_server 配置登录

    新运行uc_server环境,先配置好ucenter链接-----这部很重要,我从新环境中安装下载的discuz代码,这部没配置,密码又不知道,怎么更改调试,都不起作用,在框架中,跳转到了原来线上的u ...

  10. 莫队+分块 BZOJ 3809

    3809: Gty的二逼妹子序列 Time Limit: 80 Sec  Memory Limit: 28 MBSubmit: 1634  Solved: 482[Submit][Status][Di ...