洛谷题目链接:[SDOI2011]消防

题目描述

某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000)。

这个国家的人对火焰有超越宇宙的热情,所以这个国家最兴旺的行业是消防业。由于政府对国民的热情忍无可忍(大量的消防经费开销)可是却又无可奈何(总统竞选的国民支持率),所以只能想尽方法提高消防能力。

现在这个国家的经费足以在一条边长度和不超过s的路径(两端都是城市)上建立消防枢纽,为了尽量提高枢纽的利用率,要求其他所有城市到这条路径的距离的最大值最小。

你受命监管这个项目,你当然需要知道应该把枢纽建立在什么位置上。

输入输出格式

输入格式:

输入包含n行:

第1行,两个正整数n和s,中间用一个空格隔开。其中n为城市的个数,s为路径长度的上界。设结点编号以此为1,2,……,n。

从第2行到第n行,每行给出3个用空格隔开的正整数,依次表示每一条边的两个端点编号和长度。例如,“2 4 7”表示连接结点2与4的边的长度为7。

输出格式:

输出包含一个非负整数,即所有城市到选择的路径的最大值,当然这个最大值必须是所有方案中最小的。

输入输出样例

输入样例#1:

5 2

1 2 5

2 3 2

2 4 4

2 5 3

输出样例#1:

5

输入样例#2:

8 6

1 3 2

2 3 2

3 4 6

4 5 3

4 6 4

4 7 2

7 8 3

输出样例#2:

5

说明

【数据规模和约定】

对于20%的数据,n<=300。

对于50%的数据,n<=3000。

对于100%的数据,n<=300000,边长小等于1000。


一句话题意: 给出一颗树,在树上选一条长度小于等于\(s\)的一条简单路径,要求出其他所有点到选定路径上的点的距离的最小值.


题解: 首先我们知道,每一个点到树上最远的另一个点,那另一个点一定在直径上.所以我们可以直接枚举直径上的点,然后在找直径上的点到其他点的距离最大是多少.

先来想一下暴力要怎么做(暴力分可以参照树网的核, 其实是同一道题).

我们可以先处理出树上的一条直径,然后再暴力枚举直径上的两个端点,再求出其他点到直径上的点最大的距离是多少.显然这样是\(O(n^3)\)的.

然后观察一下题目的性质,显然在直径上取的距离越大越优,因为如果选取的长度变长,到其他点的距离是一定不会减小的,而只有可能缩小,所以可以枚举一个起点,然后直接取\(k\)的长度,再\(O(k)\)验证,复杂度\(O(n*k)\).

但是这样还是不够我们通过这道题.然后我们发现,答案是具有单调性的.感性理解一下,如果最长距离越大,也就越容易满足,反之则反.所以我们可以二分最大距离,然后\(O(n)\)枚举起点验证,总复杂度\(O(nlogn)\).

其实这题还有更好的算法,我们可以发现,在直径上取最大值的时候是通过移动左右指针来实现的,也就是说我们可以用单调队列来优化这个过程.这样复杂度就降到了\(O(n)\).这里我是使用的这种方法.

#include<cstdio>
#include<iostream>
using namespace std;
const int N = 300000+5; int n, s, last[N], ecnt = 0;
int dep[N], mx[N], fa[N], len = 0, ans = 0, f[N], L, R, vis[N], pre[N], cnt = 0, node[N], q[N], dist[N], pos[N]; struct edge{
int to, nex, w;
}e[N*2]; void add(int x, int y, int z){
e[++ecnt].to = y, e[ecnt].w = z, e[ecnt].nex = last[x], last[x] = ecnt;
} void dfs(int x, int las, int deep){
dep[x] = deep, fa[x] = las;
for(int to, i=last[x];i;i=e[i].nex){
to = e[i].to; if(to == las) continue;
dfs(to, x, deep+1);
if(len < f[x]+f[to]+e[i].w) len = f[x]+f[to]+e[i].w, L = pre[x], R = pre[to];
if(f[x] < f[to]+e[i].w) f[x] = f[to]+e[i].w, pre[x] = pre[to];
}
} int get_dis(int x, int f){
int maxx = 0;
for(int to, i=last[x];i;i=e[i].nex){
to = e[i].to;
if(vis[to] || to == f) continue;
maxx = max(maxx, get_dis(to, x)+e[i].w);
}
return maxx;
} void dfs2(int x, int lca){
if(x == lca){ node[++cnt] = x; return; }
dfs2(fa[x], lca), node[++cnt] = x;
} void init(){
for(int i=2;i<=cnt;i++)
for(int j=last[node[i]];j;j=e[j].nex)
if(e[j].to == node[i-1]) dist[node[i]] = dist[node[i-1]]+e[j].w;
} void tag(int x, int y){
int lca, a = x, b = y;
if(dep[a] < dep[b]) swap(a, b);
while(dep[a] > dep[b]) vis[a] = 1, a = fa[a];
if(a == b) vis[a] = 1, lca = a;
else {
while(a != b) vis[a] = vis[b] = 1, a = fa[a], b = fa[b];
vis[a] = 1, lca = a;
}
while(x != lca) node[++cnt] = x, x = fa[x];
dfs2(y, lca), init();
for(int i=1;i<=cnt;i++) mx[node[i]] = max(mx[node[i]], get_dis(node[i], -1));
} int solve(){
int h = 1, t = 0, h1 = 1, t1 = 0, res = 1e9;
for(int i=1;i<=cnt;i++){
while(h <= t && mx[node[q[t]]] < mx[node[i]]) t--; q[++t] = i, pos[++t1] = i;
while(h <= t && h1 <= t1 && dist[node[pos[t1]]]-dist[node[pos[h1]]] > s)
q[h] == pos[h1] ? h1++, h++ : h1++;
res = min(res, max(mx[node[q[h]]], max(dist[node[pos[h1]]], dist[node[cnt]]-dist[node[pos[t1]]])));
}
return res;
} int main(){
ios::sync_with_stdio(false);
int x, y, z; cin >> n >> s;
for(int i=1;i<=n;i++) pre[i] = i;
for(int i=1;i<n;i++) cin >> x >> y >> z, add(x, y, z), add(y, x, z);
dfs(1, -1, 1), tag(L, R);
cout << solve() << endl;
return 0;
}

[洛谷P2491] [SDOI2011]消防的更多相关文章

  1. BZOJ2243 洛谷2486 [SDOI2011]染色 树链剖分

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2243 题目传送门 - 洛谷2486 题意概括 一棵树,共n个节点. 让你支持以下两种操作,共m次操 ...

  2. 洛谷 P2495 [SDOI2011]消耗战(虚树,dp)

    题面 洛谷 题解 虚树+dp 关于虚树 了解一下 具体实现 inline void insert(int x) { if (top == 1) {s[++top] = x; return ;} int ...

  3. 洛谷 P1099 树网的核+P2491 [SDOI2011]消防

    写在前面:由于是双倍经验就放一块了,虽然数据范围差的有点大. 题目链接 题意:在树的直径上选择一条长度不超过s的路径使这条路径上的点到树上任意点的最大距离最小. 这题数据好像非常水,我写了上界n^2不 ...

  4. 洛谷 P2491消防 解题报告

    P2491 消防 题目描述 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个 ...

  5. 洛谷 P2491 解题报告

    P2491 消防 题目描述 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个 ...

  6. P1099 树网的核 && P2491 [SDOI2011]消防

    给定一棵树, 你可以在树的直径上确定一条长度不超过 \(S\) 的链, 使得树上离此链最长的点距离最小, 输出这个距离 P2491 数据范围为 P1099 的 \(1000\) 倍 Solution ...

  7. 【luogu P2491 [SDOI2011]消防】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2491 题外话: OI一共只有三种题--会的题,不会的题,二分题. 题解: step 1 求树的直径,把树的直 ...

  8. 洛谷 P2486 [SDOI2011]染色/bzoj 2243: [SDOI2011]染色 解题报告

    [SDOI2011]染色 题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同 ...

  9. 洛谷 P2485 [SDOI2011]计算器 解题报告

    P2485 [SDOI2011]计算器 题目描述 你被要求设计一个计算器完成以下三项任务: 1.给定y.z.p,计算y^z mod p 的值: 2.给定y.z.p,计算满足xy ≡z(mod p)的最 ...

随机推荐

  1. Python-期末练习

    1.骑车与走路:我们的校园很大很大很大大大大大……,骑个自行车去办事会很快,比如取个快递了,到其他宿舍楼找个同(nv)学(you)了.但实际上,并非去办任何事情都是骑车快,因为骑车总要找车.开锁.停车 ...

  2. joomla 出现The file Cache Storage is not supported on this platform;

    错误提示:The file Cache Storage is not supported on this platform:在这个平台上不支持文件缓存存储 出现这样的原因很简单,有两个文件夹不可写,这 ...

  3. Swift-闭包理解(二)

    简明扼要的闭包表达式 其实Swift已经为我们提供了很多简化的语法,可以让我们保证代码的高可读性和维护性.还用上面的例子来说明,对于  greetPeople 这个全局函数来说,其实只需要使用一次,所 ...

  4. c++ new 堆 栈

    根据32位的Windows系统默认有2GB的用户空间,则不能new超过2GB的,执行下列代码: ***]; 会出现下面的错误 error C2148: 数组的总大小不得超过 0x7fffffff 字节 ...

  5. 关于对 NUMA 理解(学习笔记,便于以后查阅)

    对NUMA的理解: NUMA是多核心CPU架构中的一种,其全称为Non-Uniform Memory Access,简单来说就是在多核心CPU中,机器的物理内存是分配给各个核的,架构简图如下所示: 每 ...

  6. HTML5拖拽练习

    HTML5提供专门的拖拽与拖放的API,以后实现这类效果就不必乱折腾了 相关属性和事件如下: 1.DataTransfer 对象:退拽对象用来传递的媒介,使用一般为Event.dataTransfer ...

  7. BZOJ 1076 奖励关(状压期望DP)

    当前得分期望=(上一轮得分期望+这一轮得分)/m dp[i,j]:第i轮拿的物品方案为j的最优得分期望 如果我们正着去做,会出现从不合法状态(比如前i个根本无法达到j这种方案),所以从后向前推 如果当 ...

  8. 【bzoj2073】[POI2004]PRZ 状态压缩dp

    题目描述 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍在桥上的人都不能超过一定的限制. 所以这只队伍过桥时只能分批 ...

  9. Android UI设计的基本元素有哪些

    在android app开发如火如荼的今天,如何让自己的App受人欢迎.如何增加app的下载量和使用量....成为很多android应用开发前,必须讨论的问题.而ui设计则是提升客户视觉体验度.提升下 ...

  10. openstack之Glance介绍

    什么是Glance glance即image service(镜像服务),是为虚拟机的创建提供镜像服务 为什么要有Glance 我们基于openstack是构建基本的Iaas平台对外提供虚机,而虚机在 ...