4326: NOIP2015 运输计划

Time Limit: 30 Sec  Memory Limit: 128 MB
Submit: 1388  Solved: 860
[Submit][Status][Discuss]

Description

公元 2044 年,人类进入了宇宙纪元。L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球。小 P 掌管一家物流公司, 该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从 ui 号星球沿最快的宇航路径飞行到 vi 号星球去。显然,飞船驶过一条航道是需要时间的,对于航道 j,任意飞船驶过它所花费的时间为 tj,并且任意两艘飞船之间不会产生任何干扰。为了鼓励科技创新, L 国国王同意小 P 的物流公司参与 L 国的航道建设,即允许小P 把某一条航道改造成虫洞,飞船驶过虫洞不消耗时间。在虫洞的建设完成前小 P 的物流公司就预接了 m 个运输计划。在虫洞建设完成后,这 m 个运输计划会同时开始,所有飞船一起出发。当这 m 个运输计划都完成时,小 P 的物流公司的阶段性工作就完成了。如果小 P 可以自由选择将哪一条航道改造成虫洞, 试求出小 P 的物流公司完成阶段性工作所需要的最短时间是多少?

Input

第一行包括两个正整数 n,m,表示 L 国中星球的数量及小 P 公司预接的运输计划的数量,星球从 1 到 n 编号。接下来 n−1 行描述航道的建设情况,其中第 i 行包含三个整数 ai,bi 和 ti,表示第 i 条双向航道修建在 ai 与 bi 两个星球之间,任意飞船驶过它所花费的时间为 ti。数据保证 1≤ai,bi≤n 且 0≤ti≤1000。接下来 m 行描述运输计划的情况,其中第 j 行包含两个正整数 uj 和 vj,表示第 j 个运输计划是从 uj 号星球飞往 vj号星球。数据保证 1≤ui,vi≤n

Output

输出文件只包含一个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间。

Sample Input

6 3
1 2 3
1 6 4
3 1 7
4 3 6
3 5 5
3 6
2 5
4 5

Sample Output

11

HINT

将第 1 条航道改造成虫洞: 则三个计划耗时分别为:11,12,11,故需要花费的时间为 12。
将第 2 条航道改造成虫洞: 则三个计划耗时分别为:7,15,11,故需要花费的时间为 15。
将第 3 条航道改造成虫洞: 则三个计划耗时分别为:4,8,11,故需要花费的时间为 11。
将第 4 条航道改造成虫洞: 则三个计划耗时分别为:11,15,5,故需要花费的时间为 15。
将第 5 条航道改造成虫洞: 则三个计划耗时分别为:11,10,6,故需要花费的时间为 11。
故将第 3 条或第 5 条航道改造成虫洞均可使得完成阶段性工作的耗时最短,需要花费的时间为 11。

题目链接:BZOJ 4326

哇这题居然有权限可以做,真是感动啊……中文题题意就不说了,来西安集训的这几天老师介绍了这题,说是二分答案balabala,然后介绍了树上差分这种东西,差分嘛,我们都知道是利用前缀和来做的,这题如何二分答案?显然是把所有大于路径长度大于当前判定答案mid的路径取出,然后看这些路径的最大值减去最大可减少的一条边是否小于等于mid,为什么是交集?我们需要的是需要减少一条边来让所有的超出mid的边均小于等于mid,如果是非交集边显然总有至少一条路径仍然还是大于mid,那么我们如何求这些原路径长度大于mid交集边呢?

求边问题就成了求一些路径被选出来的所有边覆盖过,这里就用到了树上差分这种东西,对于所有选出来的边,进行$val_v++$、$val_u++$、$val_{lca(u,v)}-=2$,然后从子节点自下至上统计一个到根节点的前缀和,那么每一个节点的值就是它到父亲边被覆盖过的次数,但是每一次从儿子DFS到根复杂度很可能会爆啊,这里可以把节点用后序遍历存下来,使得父节点一定在子节点统计完再累加,就变成$O(n)$的求前缀和复杂度了……。把选边的过程改成先排序预处理+二分位置居然还慢了一秒,无语了。最后我想说namespace大法好啊,写起来酷炫又避免了同名函数的尴尬

代码:

#include <stdio.h>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <string>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 300010;
struct edge
{int to, nxt, t;edge() {}edge(int _to, int _nxt, int _t): to(_to), nxt(_nxt), t(_t) {}
} E[N << 1];
int head[N], tot;
int sum[N], F[N], D[N << 1], ver[N << 1], ts, fa[N], dp[N << 1][20];
int tim[N], arr[N], sz, cost[N];
int U[N], V[N], LCA[N], Dis[N];
int n, m;void init()
{CLR(head, -1);tot = 0;ts = 0;sz = 0;
}
inline void add(int s, int t, int ti)
{E[tot] = edge(t, head[s], ti);head[s] = tot++;
}
void dfs(int u, int f, int dep, int sumt)
{ver[++ts] = u;F[u] = ts;D[ts] = dep;fa[u] = f;tim[u] = sumt;for (int i = head[u]; ~i; i = E[i].nxt){int v = E[i].to;if (v != f){cost[v] = E[i].t;dfs(v, u, dep + 1, sumt + E[i].t);ver[++ts] = u;D[ts] = dep;}}arr[++sz] = u;
}
namespace RMQ
{void init(int l, int r){int i, j;for (i = l; i <= r; ++i)dp[i][0] = i;for (j = 1; l + (1 << j) - 1 <= r; ++j){for (i = l; i + (1 << j) - 1 <= r; ++i){int a = dp[i][j - 1], b = dp[i + (1 << (j - 1))][j - 1];dp[i][j] = D[a] < D[b] ? a : b;}}}int LCA(int u, int v){int l = F[u], r = F[v];if (l > r)swap(l, r);int len = r - l + 1, k = 0;while (1 << (k + 1) <= len)++k;int a = dp[l][k], b = dp[r - (1 << k) + 1][k];return D[a] < D[b] ? ver[a] : ver[b];}
}
int check(int t)
{CLR(sum, 0);int ecnt = 0;int Maxcost = 0;for (int i = 0; i < m; ++i){if (Dis[i] > t){if (Dis[i] > Maxcost)Maxcost = Dis[i];++ecnt;++sum[U[i]];++sum[V[i]];sum[LCA[i]] -= 2;}}for (int i = 1; i <= sz; ++i){int u = arr[i];sum[fa[u]] += sum[u];}int Maxreduce = 0;for (int i = 1; i <= n; ++i)if (sum[i] == ecnt && cost[i] > Maxreduce)Maxreduce = cost[i];return Maxcost - Maxreduce <= t;
}
int main(void)
{int i, a, b, t;while (~scanf("%d%d", &n, &m)){init();for (i = 1; i < n; ++i){scanf("%d%d%d", &a, &b, &t);add(a, b, t);add(b, a, t);}dfs(1, 0, 0, 0);RMQ::init(1, ts);for (i = 0; i < m; ++i){scanf("%d%d", U + i, V + i);LCA[i] = RMQ::LCA(U[i], V[i]);Dis[i] = tim[U[i]] + tim[V[i]] - (tim[LCA[i]] << 1);}int L = 0, R = *max_element(Dis, Dis + m);int ans = 0;while (L <= R){int mid = MID(L, R);if (check(mid)){R = mid - 1;ans = mid;}elseL = mid + 1;}printf("%d\n", ans);}return 0;
}

转载于:https://www.cnblogs.com/Blackops/p/7300188.html

BZOJ 4326 NOIP2015 运输计划(树上差分+LCA+二分答案)相关推荐

  1. P2680 运输计划(树上差分+lca+二分)

    题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间 ...

  2. [NOIP 2015]运输计划-[树上差分+二分答案]-解题报告

    [NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...

  3. cogs2109 [NOIP2015] 运输计划

    cogs2109 [NOIP2015] 运输计划 二分答案+树上差分. STO链剖巨佬们我不会(太虚伪了吧 首先二分一个答案,下界为0,上界为max{路径长度}. 然后判断一个答案是否可行,这里用到树 ...

  4. 洛谷P2680:运输计划(倍增、二分、树上差分)

    传送门 文章目录 题目描述 解析 问题 代码 题目描述 解析 求最大值的最小值 容易想到二分 然后...就没有然后了... 看了题解 学会了一个新技能:树上差分 (其实学长之前好像讲过...) 一般的 ...

  5. Distance on the tree(树上倍增+主席树+树上差分+lca)南昌网络赛

    题目链接:南昌邀请赛网络赛Distance on the tree 统计一条链上边权小于k的边数. 树上差分,对于边权来说,一条链上的边的条数=sum[x]+sum[y]-2*sum[lca(x,y) ...

  6. P3128-最大流Max Flow【树上差分,LCA】

    正题 题目大意 一棵树 若干条路径,哪个点经过的路径最多,求路径条数. 解题思路 对于每条路径计算一次LCALCALCA,然后树上差分就好了. codecodecode #include<cst ...

  7. 【codevs4632】【BZOJ4326】运输计划,链剖+二分+差分

    传送门1 传送门2 写在前面: 当初洗澡的时候脑补了下这个题,觉得很简单直到看到题面,才发现自己记错了,自此开始不归路 思路:这里的链剖实际上就是求每个操作的路径长度(也可以LCA求),然后我想到了二 ...

  8. $Luogu2680/NOIp2015$ 运输计划

    传送门 $Sol$ 最暴力的做法就是枚举最长链上的边,然后再算一次所有的链长,更新$ans$. 这里要求最大的最小,容易想到二分答案.对于二分的值$mid$,扫一遍所有的链,若链长小于等于$mid$, ...

  9. 【NOIP2015】D2-T1跳石头,二分答案

    如果这道题没有写60分的堆加贪心而是二分,如果我在考试前我能写一道自己一直在躲避的二分答案,如果我能骗到第三题哪怕15分,结果都会不同,可惜没如果-- ------------------------ ...

最新文章

  1. 『TensorFlow』数据读取类_data.Dataset
  2. .Net平台开发的技术规范与实践精华总结 (转)
  3. go语言值得学习的开源项目推荐
  4. SIT与UAT的分别
  5. 基于hadoop的商品推荐系统_【论文笔记】基于矩阵分解的推荐系统
  6. 逻辑回归能摆平二分类因变量,那……不止二分类呢?
  7. System verilog随机系统函数$urandom_range使用方法
  8. mariadb不支持load data_不修改代码打包python机器学习工程
  9. 解决从k8s.gcr.io/gcr.io/quay.io等地址拉取镜像失败问题(Kubernetes国内镜像仓库地址)
  10. vf更改当前路径_这份 window.location 备忘单,让你更有条理解决地址路径问题!...
  11. git学习(三)版本的前进后退
  12. C++ 入门2 ---- 类型转换
  13. qt菜单栏按钮点击事件_如何用Axure画出Web后台产品的菜单栏组件
  14. 一次网易游戏测试(外包)面试
  15. 十五个免费Windows桌面系统工具(附下载)
  16. Android 自定义viewGroup实现淘宝二楼及处理多指触控事件
  17. 新手小白怎么学抖音运营?抖音运营5大技巧
  18. 《迅雷链精品课》第三课:区块链主流框架分析
  19. llqrcode.js识别二维码,解析二维码信息
  20. FontStruct——制作你自己的个性化字体

热门文章

  1. Conversion to Dalvik format failed with error 1
  2. oracle 11g的em界面按钮乱码的解决办法
  3. mitdump爬取当当网APP图书目录
  4. 大数据集群某节点彻底损毁后重装系统恢复(持续更新中)
  5. notebook中安装lightgbm的gpu版本
  6. R语言版本查询以及line 1 of `undefined.cases': bad value of `47.25' for attribute `A2'的解决
  7. 第五章functions.py中的交叉熵代码解释
  8. 凸优化函数的一些概念(转)
  9. 红黑树 删除某节点后 旋转3次 举例
  10. 《机器学习》 周志华学习笔记第七章 贝叶斯分类器(课后习题)python 实现