P1084 疫情控制
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 疫情控制的更多相关文章
- [NOIP2012] 提高组 洛谷P1084 疫情控制
题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都, 也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散 ...
- 洛谷P1084 疫情控制(NOIP2012)(二分答案,贪心,树形DP)
洛谷题目传送门 费了几个小时杠掉此题,如果不是那水水的数据的话,跟列队的难度真的是有得一比... 话说蒟蒻仔细翻了所有的题解,发现巨佬写的都是倍增,复杂度是\(O(n\log n\log nw)\)的 ...
- NOIP2012 洛谷P1084 疫情控制
Description: H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情 ...
- 洛谷 P1084 疫情控制 —— 二分+码力
题目:https://www.luogu.org/problemnew/show/P1084 5个月前曾经写过一次,某个上学日的深夜,精疲力竭后只有区区10分,从此没管... #include< ...
- Luogu P1084 疫情控制 | 二分答案 贪心
题目链接 观察题目,答案明显具有单调性. 因为如果用$x$小时能够控制疫情,那么用$(x+1)$小时也一定能控制疫情. 由此想到二分答案,将问题转换为判断用$x$小时是否能控制疫情. 对于那些在$x$ ...
- luogu P1084 疫情控制
传送门 首先,所有军队又要尽量往上走,这样才能尽可能的封锁更多的到叶子的路径 而随着时间的增加,能封锁的路径也就越来越多,所以可以二分最终的时间 然后对于每个时间,就让能走到根的军队走到根,记录到根上 ...
- 洛谷P1084 疫情控制 [noip2012] 贪心+树论+二分答案 (还有个小bugQAQ
正解:贪心+倍增+二分答案 解题报告: 正好想做noip的题目然后又想落实学长之前讲的题?于是就找上了这题 其实之前做过,70,然后实在细节太多太复杂就不了了之,现在再看一遍感觉又一脸懵了... 从标 ...
- 2018.09.26洛谷P1084 疫情控制(二分+倍增)
传送门 好题啊. 题目要求的最大值最小,看到这里自然想到要二分答案. 关键在于怎么检验. 显然对于每个点向根走比向叶节点更优. 因此我们二分答案之后,用倍增将每个点都向上跳到跳不动为止. 这时我们ch ...
- luogu P1084疫情控制 二分
链接 loj luogu太水不要去了. 思路 二分. 每个军队在一定的时间内越往上越好. 注意一个军队可以跨过1去帮别的. 把能到1脚下的点都存下来特判. 有一种情况是这个子树内只有一个军队,但这个军 ...
随机推荐
- Sort Integers II
Given an integer array, sort it in ascending order. Use quick sort, merge sort, heap sort or any O(n ...
- linux设置开机自动启动
有很多中方法,这里只取最简单的一种: 把启动命令放到/etc/rc.d/rc.local文件里这样就可以每次启动的时候自动启动服务了, 注意给rc.local执行权限
- DotNet,PHP,Java的数据库连接代码大全(带演示代码)
C#数据库连接字符串 Web.config文件 <connectionStrings> <!--SQLServer数据库连接--> <add name="con ...
- 解题:SCOI 2008 天平
题面 我们很容易想到差分约束,但是我们建出来图之后好像并不好下手,因为我们只能得到砝码间的大小关系,并不能容易地得到每个砝码的具体重量. 于是我们有了一种神奇的思路:既然得不到具体重量我们就不求具体重 ...
- APIO2017
商旅 在广阔的澳大利亚内陆地区长途跋涉后,你孤身一人带着一个背包来到了科巴.你被这个城市发达而美丽的市场所 深深吸引,决定定居于此,做一个商人.科巴有个集市,集市用从1到N的整数编号,集市之间通过M条 ...
- Android APK打包流程
简单build流程图 官网给了我们一张非常简单的编译.打包.apk生成内容以及签名的图片.图片大体介绍了从Project到运行到设备或者模拟器的一个大体流程,我们也从中看到一个完整的apk包含如下内容 ...
- 服务器上的 Git - 在服务器上搭建 Git
http://git-scm.com/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E5%9C%A8%E6%9C%8D%E ...
- Codeforce 633.C Spy Syndrome 2
C. Spy Syndrome 2 time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- STM32自动生成精美图案
http://note.youdao.com/noteshare?id=65f237225624d22fe18f4aaaeec8db07
- Android_UiAutomator(安卓UI自动化)环境搭建
一.配置JDK环境变量 1.新建系统变量JAVA_HOME,然后输入引号内的内容(JDK安装目录) "C:\Program Files\Java\jdk1.8.0_51" ...