http://codevs.cn/problem/1218/

比较显然的倍增,但是对于跨过根需要很多讨论,总体思路是贪心。

写了一上午,不想再说什么了

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 100003;
int in() {
int k = 0, fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = (k << 3) + (k << 1) + c - '0';
return k * fh;
} struct node {int nxt, to, w;} E[N << 1];
struct data {
ll left; int from;
bool operator < (const data &A) const {
return left < A.left;
}
} A[N], B[N];
struct data2 {
int id, dis;
bool operator < (const data2 &A) const {
return dis < A.dis;
}
} P[N];
int f[N][18], n, m, cnt = 0, point[N], L[N], R[N], w[N], Army[N], a[N], nxt[N], upto[N];
ll c[N][18];
bool mark[N]; void ins(int u, int v, int w) {E[++cnt] = (node) {point[u], v, w}; point[u] = cnt;} void dfs(int x) {
L[x] = ++cnt;
w[cnt] = x;
for(int i = point[x]; i; i = E[i].nxt)
if (E[i].to != f[x][0]) {
f[E[i].to][0] = x;
c[E[i].to][0] = E[i].w;
dfs(E[i].to);
}
R[x] = cnt;
} void pushup_mark(int x) {
if (mark[x]) return;
bool flag = false, marknow = true;
for(int i = point[x]; i; i = E[i].nxt)
if (E[i].to != f[x][0]) {
pushup_mark(E[i].to);
flag = true;
marknow &= mark[E[i].to];
}
if (flag) mark[x] = marknow;
} bool cmp_forMrazer(data X, data Y) {
return X.from == Y.from ? X.left < Y.left : X.from < Y.from;
} bool can(ll up) {
int tmp, tot = 0, tot2 = 0, tot3 = 0; ll ret;
memset(mark, 0, sizeof(bool) * (n + 1));
for(int i = 1; i <= m; ++i) {
ret = up; tmp = Army[i];
for(int j = 17; j >= 0; --j)
if (f[tmp][j] && f[tmp][j] != 1 && c[tmp][j] <= ret) {
ret -= c[tmp][j];
tmp = f[tmp][j];
}
if (c[tmp][0] <= ret) A[++tot] = (data) {ret - c[tmp][0], tmp};
else mark[tmp] = true;
} // for(int i = 1; i <= tot; ++i) printf("left = %I64d from = %d\n", A[i].left, A[i].from); for(int i = point[1]; i; i = E[i].nxt)
pushup_mark(E[i].to); stable_sort(A + 1, A + tot + 1, cmp_forMrazer); for(int i = 1; i <= tot; ++i)
if (!mark[A[i].from])
if (A[i].left <= c[A[i].from][0])
mark[A[i].from] = true;
else
B[++tot3] = A[i];
else
B[++tot3] = A[i];
// printf("%d\n", tot3);
// for(int i = 1; i <= tot3; ++i) printf("left = %I64d from = %d\n", B[i].left, B[i].from); for(int i = point[1]; i; i = E[i].nxt)
if (!mark[E[i].to])
P[++tot2] = (data2) {E[i].to, c[E[i].to][0]}; stable_sort(B + 1, B + tot3 + 1);
stable_sort(P + 1, P + tot2 + 1); // printf("%d %d\n", tot3, tot2); if (tot3 < tot2) return false;
for(; tot3 && tot2; --tot3, --tot2)
if (B[tot3].left < P[tot2].dis) return false;
return true;
} int main() {
n = in();
int u, v, w;
for(int i = 1; i < n; ++i) {
u = in(); v = in(); w = in();
ins(u, v, w);
ins(v, u, w);
} dfs(1);
for(int j = 1; j <= 17; ++j)
for(int i = 1; i <= n; ++i) {
f[i][j] = f[f[i][j - 1]][j - 1];
if (f[i][j]) c[i][j] = c[i][j - 1] + c[f[i][j - 1]][j - 1];
}
m = in();
for(int i = 1; i <= m; ++i) Army[i] = in();
ll left = 0, right = 50000000000000ll, mid;
while (left < right) {
mid = (left + right) >> 1; //printf("left = %I64d mid = %I64d right = %I64d\n", left, mid, right);
if (can(mid)) right = mid;
else left = mid + 1;
} printf("%lld\n", left);
return 0;
}

_(:з」∠)_

【CodeVS 1218】【NOIP 2012】疫情控制的更多相关文章

  1. 【NOIP 2012 疫情控制】***

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

  2. NOIP 2012 疫情控制(二分+贪心+倍增)

    题解 二分时间 然后一个显然的事是一个军队向上爬的越高它控制的点越多 所以首先军队尽量往上爬. 当一个军队可以爬到根节点我们记录下它的剩余时间T和它到达根结点时经过的根节点的子节点son. 当一个军队 ...

  3. 基础算法(二分,贪心):NOIP 2012 疫情控制

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

  4. noip 2012 疫情控制

    /* 考试的时候没想出正解 也没打暴力 时间不够了 随便yy了几种情况按出现的先后顺序处理而没有贪心 的了20分 不粘了 正解是围绕首都的儿子来搞的 显然先二分答案 对于每个限定的最大时间 我们尝试着 ...

  5. 【NOIP】提高组2012 疫情控制

    [题意]n个点的树,1为根,要求删除一些点使得截断根节点和所有叶子结点的路径(不能删根,可以删叶子).有m支军队在m个点上,每时刻所有军队可以走一步,最终走到的地方就是删除的点,求最短时间. [算法] ...

  6. Codevs 1218 疫情控制 2012年NOIP全国联赛提高组

    1218 疫情控制 2012年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description H 国有 n 个城市,这 ...

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

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

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

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

  9. [NOIP2012] day2 T3疫情控制

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

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

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

随机推荐

  1. 阿里云+wordpress搭建个人博客网站【小白专用的图文教程】

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  2. KSFramework:集成U3D热重载框架 - README

    KSFramework KEngine + SLua+ Framework = KSFramework KSFramework是一个整合KEngine.SLua的Unity 5开发框架,并为程序.美术 ...

  3. XSS安全性过滤

    XSS攻击很多发生在用户在可以输入的地方输入了不友好的内容,根本处理方法是在输入内容中进行过滤 PHP或者java,基本都有现成的jar包或者php框架,调用自动过滤用户的输入内容,避免了XSS 防御 ...

  4. PHP加载另一个文件类的方法

    加载另一个文件类的方法 当前文件下有a.php 和b.php,想要在class b中引入class a <?php    class a    {        public $name = ' ...

  5. Maven学习(四)Maven 命令行选项

    说明: 1.使用-选项时,和后面的参数之间可以不要空格.而使用--选项时,和后面的参数之    间必须有空格.如下面的例子: $ mvn help:describe -Dcmd=compiler:co ...

  6. [No00001E]不出国,学口语-出国口语自然好?才怪咧!

  7. 装完Centos7提示Initial setup of CentOS Linux 7 (core)(转载)

    http://www.th7.cn/system/lin/201603/156762.shtml

  8. 030医疗项目-模块三:药品供应商目录模块——供货商药品目录查询功能----------Dao层:基本的查询语句的编写

    我们安装显示的要求: 我们能看到显示的目录里面有:供货企业的名字(这个数据来自于供货商的表[usergys]),流水号,通用名,剂型(这些都来自药品信息表),供货的状态(这个呢在gysypml_con ...

  9. DEDECMS之九 文章采集

    到很多网友都为织梦(DEDECMS)的采集教程头疼,的确,官方出的教程太笼统了,什么都没说,换个网站你什么都做不了,这个教程是最详尽的教程,让你一看即会! 一.列表采集 第一步.我们打开织梦后台点击采 ...

  10. AlwaysOn--Backup Preference

    AlwaysOn group的一个新特性是允许在secondary replica进行backup,将backup的负载从primary replica上移除去. 并且提供了Backup prefer ...