P1084 疫情控制

题目描述

H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点。

H 国的首都爆发了一种危害性极高的传染病。当局为了控制疫情,不让疫情扩散到边境城市(叶子节点所表示的城市),决定动用军队在一些城市建立检查点,使得从 首都到边境城市的每一条路径上都至少有一个检查点,边境城市也可以建立检查点。但特别要注意的是,首都是不能建立检查点的。

现在,在 H 国的一些城市中已经驻扎有军队,且一个城市可以驻扎多个军队。一支军队可以在有道路连接的城市间移动,并在除首都以外的任意一个城市建立检查点,且只能在 一个城市建立检查点。一支军队经过一条道路从一个城市移动到另一个城市所需要的时间等于道路的长度(单位:小时)。

请问最少需要多少个小时才能控制疫情。注意:不同的军队可以同时移动。

输入输出格式

输入格式:

第一行一个整数 n,表示城市个数。

接下来的 n-1 行,每行 3 个整数,u、v、w,每两个整数之间用一个空格隔开,表示从城市 u 到城市 v 有一条长为 w 的道路。数据保证输入的是一棵树,且根节点编号为 1。

接下来一行一个整数 m,表示军队个数。

接下来一行 m 个整数,每两个整数之间用一个空格隔开,分别表示这 m 个军队所驻扎的城市的编号。

输出格式:

共一行,包含一个整数,表示控制疫情所需要的最少时间。如果无法控制疫情则输出-1。

输入输出样例

输入样例#1:

4
1 2 1
1 3 2
3 4 3
2
2 2
输出样例#1:

3

说明

【输入输出样例说明】

第一支军队在 2 号点设立检查点,第二支军队从 2 号点移动到 3 号点设立检查点,所需时间为 3 个小时。

【数据范围】

保证军队不会驻扎在首都。

对于 20%的数据,2≤ n≤ 10;

对于 40%的数据,2 ≤n≤50,0<w <10^5;

对于 60%的数据,2 ≤ n≤1000,0<w <10^6;

对于 80%的数据,2 ≤ n≤10,000;

对于 100%的数据,2≤m≤n≤50,000,0<w <10^9。

NOIP 2012 提高组 第二天 第三题

【题解】

倍增写反了调了半天。。

各种细节

写一下能想到的几点;

1、倍增写反了 淦

2、往根节点跳,跳不到就留下。跳上去回不来,如果那个点没有留下的,就留下;如果有留下的,就比较

剩余值的大小,小的留下。为什么回不去,且那个点没有留下的,就要留下?因为这个点回不去,一定需要

其他点填补,其他点剩余值比这个点大,不如让其他点做更大的事情

代码比较乱

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm> const long long MAXN = + ;
const long long MAXM = + ; inline void read(long long &x)
{
x = ;char ch = getchar(), c = ch;
while(ch < '' || ch > '')c = ch, ch = getchar();
while(ch <= '' && ch >= '')x = x * + ch - '', ch = getchar();
if(c == '-')x = -x;
} struct Edge
{
long long u,v,next,w;
Edge(long long _u, long long _v, long long _w, long long _next){u = _u;v = _v;w = _w;next = _next;}
Edge(){}
}edge[MAXN << ];
long long head[MAXN], cnt; inline void insert(long long a, long long b, long long c)
{
edge[++cnt] = Edge(a, b, c, head[a]);
head[a] = cnt;
} long long rank[MAXN],n,m,l,r,mid,fa[MAXN],have[MAXN],ans,have2[MAXN]; long long b[MAXN],p[][MAXN],len[][MAXN],deep[MAXN]; void dfs(long long u)
{
b[u] = ;
for(register long long pos = head[u];pos;pos = edge[pos].next)
{
long long v = edge[pos].v;
if(b[v]) continue;
fa[v] = u;
deep[v] = deep[u] + ;
p[][v] = u, len[][v] = edge[pos].w;
dfs(v);
}
}
long long M = ; void yuchuli()
{
while(( << M) <= n) ++ M;
-- M; for(register long long j = ;j <= M;++ j)
for(register long long i = ;i <= n;++ i)
p[j][i] = p[j - ][p[j - ][i]];
for(register long long j = ;j <= M;++j)
for(register long long i = ;i <= n;++ i)
len[j][i] = len[j - ][i] + len[j - ][p[j - ][i]];
} long long dfs2(long long u)
{
if(have2[u])return ;
long long flag = ;
for(register long long pos = head[u];pos;pos = edge[pos].next)
{
long long v = edge[pos].v;
if(fa[u] == v)continue;
flag = dfs2(v);
if(!flag)return ;
}
return flag;
} long long node1[MAXN], tot; long long tot2, mi[MAXN]; struct TT
{
int re, rank;
TT(int _re, int _rank){re = _re;rank = _rank;}
TT(){}
}tt[MAXN]; bool cmpp(TT a, TT b)
{
return a.re < b.re;
} long long check(long long ma)
{
memset(tt, , sizeof(tt));
memset(have2, , sizeof(have2));
memset(mi, , sizeof(mi));
tot2 = ; for(register long long i = ;i <= m;++ i)
{
long long now = rank[i], s = ;
if(now == )
{
tt[++tot2].re = ma;
tt[tot2].rank = now;
continue;
}
for(register long long j = M;j >= ;-- j)
if(s + len[j][now] <= ma && p[j][now] > )
s += len[j][now], now = p[j][now];
if(fa[now] == && ma - s - len[][now] > )
{
if(ma - s - len[][now] < len[][now])
{
if(!mi[now]) mi[now] = ma - s - len[][now], have2[now] = ;
else if(mi[now] > ma - s - len[][now])tt[++tot2].re = mi[now], mi[now] = ma - s - len[][now], tt[tot2].rank = now;
else tt[++tot2].re = ma - s - len[][now], tt[tot2].rank = now;
}
else tt[++tot2].re = ma - s - len[][now], tt[tot2].rank = now;
}
else ++ have2[now], mi[now] = ma - s - len[][now];
}
for(register int i = ;i <= n;++ i)
{
int tmp = have2[i];
-- have2[i];
if(fa[i] == && dfs2(i) && mi[i] > )
{
tt[++tot2].re = mi[i]; tt[tot2].rank = i;
-- tmp;
}
have2[i] = tmp;
}
std::sort(tt + , tt + + tot2, cmpp);
long long now = ;
for(register long long i = ;i <= tot;++ i)
{
if(!dfs2(node1[i]))
{
if(now > tot2)return ;
while(tt[now].re < len[][node1[i]] && now <= tot2)++ now;
if(now > tot2)return ;
++ now;
}
}
return ;
} bool cmp(long long a, long long b)
{
return len[][a] < len[][b];
} int main()
{
read(n);
register long long tmp1, tmp2, tmp3;
for(register long long i = ;i < n;++i)
{
read(tmp1), read(tmp2), read(tmp3);
insert(tmp1, tmp2, tmp3);
insert(tmp2, tmp1, tmp3);
r += tmp3;
}
read(m);
for(register long long j = ;j <= m;++j)
read(rank[j]), have[rank[j]] = ;
deep[] = ;
dfs();
for(register long long pos = head[];pos;pos = edge[pos].next)
{
long long v = edge[pos].v;
if(v != ) node1[++tot] = v;
}
yuchuli();
std::sort(node1 + , node1 + + tot, cmp);
l = ;
while(l <= r)
{
mid = (l + r) >> ;
if(check(mid)) ans = mid, r = mid - ;
else l = mid + ;
}
if(!ans)
{
printf("-1");
return ;
}
if(check())ans = ;
printf("%lld", ans);
return ;
}

NOIP2012Day2T3疫情控制

洛谷P1084 [NOIP2012提高组Day2T3]疫情控制的更多相关文章

  1. 洛谷P1083 [NOIP2012提高组Day2T2]借教室

    P1083 借教室 题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借 ...

  2. 洛谷P1315 [NOIP2011提高组Day2T3] 观光公交

    P1315 观光公交 题目描述 风景迷人的小城Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第 0 分钟出现在 1号 ...

  3. 洛谷P1080 [NOIP2012提高组D1T2]国王游戏 [2017年5月计划 清北学堂51精英班Day1]

    P1080 国王游戏 题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 ...

  4. 【分块】【常数优化】【Orz faebdc】洛谷 P1083 NOIP2012提高组 借教室

    分块90分. By AutSky_JadeK [重点在下面] #include<cstdio> #include<cmath> using namespace std; #de ...

  5. 洛谷P1979 [NOIP2013提高组Day2T3]华容道

    P1979 华容道 题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少 ...

  6. 【noip 2012】提高组Day2T3.疫情控制

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

  7. 洛谷 P2678 & [NOIP2015提高组] 跳石头

    题目链接 https://www.luogu.org/problemnew/show/P2678 题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布 ...

  8. 洛谷 P1025 & [NOIP2001提高组] 数的划分(搜索剪枝)

    题目链接 https://www.luogu.org/problemnew/show/P1025 解题思路 一道简单的dfs题,但是需要剪枝,否则会TLE. 我们用dfs(a,u,num)来表示上一个 ...

  9. 洛谷P1514 [NOIP2010提高组T4]引水入城

    P1514 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城 ...

随机推荐

  1. (转)第01节:初识简单而且强大的Fabric.js库

    Fabric.js是一个功能强大和简单Javascript HTML5的canvas库.Fabric提供了很多可以互动的Canvas元素,还在canvas上提供了SVG的语法分析器. 你可以轻松的使用 ...

  2. LeeCode-Single Number III

    Given an array of numbers nums, in which exactly two elements appear only once and all the other ele ...

  3. 项目接入即时聊天客服系统(环信系统)PHP后端操作

    环信工作原理: 一.由于环信没有直接的接口来主动调取本项目中的用户数据,所有用户信息必须在环信服务器上注册对应信息成为环信的用户:(这样才能当用户进入聊天时显示其基本信息,如:名称.昵称.电话.邮箱等 ...

  4. windows 可执行文件分析

    windows可执行文件是什么? 是具有PE文件格特性的文件,例如:.exe.dll.ocx等文件. 注:(这里只是让大家能明了一些,其实,可执行与否,和后缀没有什么关系,后缀只是windows方便管 ...

  5. <meta>标记

    <meta>的主要作用: 是提供网页的元素信息 属性: http-equiv: 功能: 默认http协议文件头信息,当信息从服务器端传到客户端时,让浏览器正确的是显示, http_equi ...

  6. php面向对象的初认识

    面向对象的基本概念 面向对象的三大特征:继承 封装 多态 类和对象: 类是一个抽象的概念 对象是一个具体的实例 张三是一个对象,李四也是一个对象.王五同样是一个对象..... 他们都隶属于“人”这个“ ...

  7. python-爬免费ip并验证其可行性

    前言 最近在重新温习python基础-正则,感觉正则很强大,不过有点枯燥,想着,就去应用正则,找点有趣的事玩玩 00xx01---代理IP 有好多免费的ip,不过一个一个保存太难了,也不可能,还是用我 ...

  8. Netty设置高低水位

    Configure high and low write watermarks   Server ServerBootstrap bootstrap = new ServerBootstrap(); ...

  9. <每日一题>题目19:简单的程序执行效率面试题

    # 将下面的函数按照执行效率高低排序.它们都接受由0至1之间的数字构成的列表作为输入.这个列表可以很长.一个输入列表的示例如下:[random.random() for i in range(1000 ...

  10. charles-截取移动端请求-设置代理

    Charles 上的设置 1.    要截取 iPhone 上的网络请求,我们首先需要将 Charles 的代理功能打开.在 Charles 的菜单栏上选择 “Proxy”–>“Proxy Se ...