洛谷P1084 [NOIP2012提高组Day2T3]疫情控制
P1084 疫情控制
题目描述
H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点。
H 国的首都爆发了一种危害性极高的传染病。当局为了控制疫情,不让疫情扩散到边境城市(叶子节点所表示的城市),决定动用军队在一些城市建立检查点,使得从 首都到边境城市的每一条路径上都至少有一个检查点,边境城市也可以建立检查点。但特别要注意的是,首都是不能建立检查点的。
现在,在 H 国的一些城市中已经驻扎有军队,且一个城市可以驻扎多个军队。一支军队可以在有道路连接的城市间移动,并在除首都以外的任意一个城市建立检查点,且只能在 一个城市建立检查点。一支军队经过一条道路从一个城市移动到另一个城市所需要的时间等于道路的长度(单位:小时)。
请问最少需要多少个小时才能控制疫情。注意:不同的军队可以同时移动。
输入输出格式
输入格式:
第一行一个整数 n,表示城市个数。
接下来的 n-1 行,每行 3 个整数,u、v、w,每两个整数之间用一个空格隔开,表示从城市 u 到城市 v 有一条长为 w 的道路。数据保证输入的是一棵树,且根节点编号为 1。
接下来一行一个整数 m,表示军队个数。
接下来一行 m 个整数,每两个整数之间用一个空格隔开,分别表示这 m 个军队所驻扎的城市的编号。
输出格式:
共一行,包含一个整数,表示控制疫情所需要的最少时间。如果无法控制疫情则输出-1。
输入输出样例
4
1 2 1
1 3 2
3 4 3
2
2 2
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]疫情控制的更多相关文章
- 洛谷P1083 [NOIP2012提高组Day2T2]借教室
P1083 借教室 题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借 ...
- 洛谷P1315 [NOIP2011提高组Day2T3] 观光公交
P1315 观光公交 题目描述 风景迷人的小城Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第 0 分钟出现在 1号 ...
- 洛谷P1080 [NOIP2012提高组D1T2]国王游戏 [2017年5月计划 清北学堂51精英班Day1]
P1080 国王游戏 题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 ...
- 【分块】【常数优化】【Orz faebdc】洛谷 P1083 NOIP2012提高组 借教室
分块90分. By AutSky_JadeK [重点在下面] #include<cstdio> #include<cmath> using namespace std; #de ...
- 洛谷P1979 [NOIP2013提高组Day2T3]华容道
P1979 华容道 题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少 ...
- 【noip 2012】提高组Day2T3.疫情控制
Description H国有n个城市,这n个城市用n-1条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点. H国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到边境 ...
- 洛谷 P2678 & [NOIP2015提高组] 跳石头
题目链接 https://www.luogu.org/problemnew/show/P2678 题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布 ...
- 洛谷 P1025 & [NOIP2001提高组] 数的划分(搜索剪枝)
题目链接 https://www.luogu.org/problemnew/show/P1025 解题思路 一道简单的dfs题,但是需要剪枝,否则会TLE. 我们用dfs(a,u,num)来表示上一个 ...
- 洛谷P1514 [NOIP2010提高组T4]引水入城
P1514 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城 ...
随机推荐
- Windows的进程间通信
对于任何一个现代的操作系统,进程间通信都是其系统结构的一个重要组成部分.而说到Windows的进程(线程)间通信,那就要看是在什么意义上说了.因为正如"Windows的跨进程操作" ...
- dns 逐级查找顺序
1.浏览器 dns 缓存 2.Windows Host 文本 3.windows 本地 dns 缓存 方法/步骤 首先我们来查看win系统内保存的dns缓存并进行清空dns缓存操作. ... 点击确定 ...
- 关于python DataFrame的学习记录
df_1 = pd.DataFrame({'A': [0, 1, 2], 'B': [3, 4, 5]}) print df_1 默认左边行index0往上递增,AB为顶部标识,数组内为内容 loc— ...
- HBase访问接口
- 1.Spring【IOC】XML方式
1.下载开发包 http://repo.springsource.org/libs-release-local/org/springframework/spring 2.创建WEB工程,引入jar包 ...
- 联想 Z470个人安装黑苹果参考
笔记本是联想 Z470,cpu i3-2350M 傻瓜图文式]Win系统下制作U盘CLOVER引导 EDIT部分 进去黑屏 U盘引导盘
- 【NOIP2018模拟11.01】树
题目 描述 题目大意 维护一个序列,支持三种操作: 1.修改一段区间,将这段区间内的所有数都andandand一个数. 2.询问区间和. 3.询问区间两两相加的平方和. N≤10000N\leq 10 ...
- 打包成exe可执行文件的方法
Python安装扩展库与打包成exe可执行文件的方法 1.安装扩展库的几种方法. 首先可能需要使用 pip install --upgrade pip 来升级本机的pip程序.然后在命令提示符环境(即 ...
- ECMAScript 5 严格模式
1. 变量必须使用var声明,杜绝不小心将本地变量声明成一个全局变量 在常规模式下,如果我们声明一个变量时省略了var关键字,解析引擎会自动将其声明为全局变量,但在严格模式下,会直接抛出异常,不会为我 ...
- JasperReports报表字段11
报表字段是代表数据源和报表模板之间的数据映射元素.字段可以在报告中的表达式进行组合,以获得所需的输出.报表模板可以包含零个或更多的<field>元素.当声明报表字段,数据源应提供相应的数据 ...