HDU 5361 In Touch (2015 多校6 1009 最短路 + 区间更新)
来源:互联网 发布:mac怎么取消隐藏文件 编辑:程序博客网 时间:2024/06/10 09:32
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5361
题意:最短路,求源点到所有点的最短距离。但与普通最短路不同的是,给出的边是某点到区间[l,r]内任意点的距离。
输入一个n,代表n个点,输入n个l[i],输入n个r[i],输入n个c[i]。
对于i,表示i到区间[i - r[i]],i - l[i]]和区间[i + l[i],i + r[i]]内的任意点的距离为c[i]。
求1到各个点的最短距离。
思路:若建边跑最短路的话,因为边过多,所以不可行。因为在最后的结果中,可能源点1到某段区间的最短路径都是一样的,所以可以在最短路的算法基础上利用线段树区间更新来维护源点1到区间的最短路径,最后只需要查询区间即可。线段树的每个结点存该区间源点到该区间点的最短路的最大值和最小值。所以叶子结点即是源点1到该点的最短路径。(思路来源队友)
代码:
#include <iostream>#include <iomanip>#include <stdio.h>#include <string>#include <string.h>#include <math.h>#include <queue>#include <set>#include <vector>#include <algorithm>using namespace std;#define lson l, m, rt << 1#define rson m + 1, r, rt << 1 | 1const long long INF = 1e18;const int N = 2e5 + 10;struct Segment { int l, r; long long d; Segment(int l = 0, int r = 0, long long d = 0) { this -> l = l; this -> r = r; this -> d = d; } friend bool operator < (Segment a, Segment b) { return a.d > b.d; }};struct Node { int used;//标记该段区间是否使用过,因为距离均为正值,所以若该区间已是最短距离,则不需要继续更新。 long long _max; long long _min;};Node node[N << 2];long long lazy[N << 2];int n;int lef[N];int rig[N];long long c[N];priority_queue<Segment> q;void pushup(int rt) { node[rt]._max = max(node[rt << 1]._max, node[rt << 1 | 1]._max); node[rt]._min = min(node[rt << 1]._min, node[rt << 1 | 1]._min); if (node[rt << 1].used == node[rt << 1 | 1].used) node[rt].used = node[rt << 1].used; else node[rt].used = -1;}void pushdown(int rt) { if (lazy[rt] != -1) { lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt]; node[rt << 1]._min = node[rt << 1]._max = lazy[rt]; node[rt << 1 | 1]._min = node[rt << 1 | 1]._max = lazy[rt]; lazy[rt] = -1; }}void build(int l, int r, int rt) { node[rt]._max = INF; node[rt]._min = INF; node[rt].used = 0; lazy[rt] = -1; if (l == r) { if (l == 1) { node[rt]._max = 0; node[rt]._min = 0; } return ; } int m = (l + r) >> 1; build(lson); build(rson); pushup(rt);}void update(long long cr, int L, int R, int l, int r, int rt) { if (node[rt]._max <= cr) return ; if (L <= l && r <= R) { node[rt]._max = cr; if (node[rt]._min > cr) { node[rt]._min = cr; q.push(Segment(l, r, cr)); lazy[rt] = cr; return ; } } if (l == r) return ; pushdown(rt); int m = (l + r) >> 1; if (L <= m) update(cr, L, R, lson); if (R > m) update(cr, L, R, rson); pushup(rt);}void querysegment(Segment ff, int l, int r, int rt) { if (node[rt].used == 1) return ; if (ff.l <= l && r <= ff.r) { if (node[rt].used == 0) { for (int i = l; i <= r; i++) { int le = i + lef[i]; int ri = min(n, i + rig[i]); if (le <= n) { update(ff.d + c[i], le, ri, 1, n, 1); } le = max(1, i - rig[i]); ri = i - lef[i]; if (ri >= 1) { update(ff.d + c[i], le, ri, 1, n, 1); } } node[rt].used = 1; return ; } } if (l == r) return ; int m = (l + r) >> 1; if (ff.l <= m) querysegment(ff, lson); if (ff.r > m) querysegment(ff, rson); pushup(rt);}bool fir;void query(int l, int r, int rt) { if (node[rt]._max == node[rt]._min) { for (int i = l; i <= r; i++) { if (node[rt]._min == INF) node[rt]._min = -1; if (!fir) { printf("%lld", node[rt]._min); fir = true; } else printf(" %lld", node[rt]._min); } return ; } if (l == r) { return ; } pushdown(rt); int m = (l + r) >> 1; query(lson); query(rson);}int main() { int t_case; scanf("%d", &t_case); for (int i_case = 1; i_case <= t_case; i_case++) { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &lef[i]); for (int i = 1; i <= n; i++) scanf("%d", &rig[i]); for (int i = 1; i <= n; i++) scanf("%lld", &c[i]); build(1, n, 1); while(!q.empty()) q.pop(); q.push(Segment(1, 1, 0)); while (!q.empty()) { Segment ff = q.top(); q.pop(); querysegment(ff, 1, n, 1); } fir = false; query(1, n, 1); printf("\n"); } return 0;}
0 0
- HDU 5361 In Touch (2015 多校6 1009 最短路 + 区间更新)
- hdu 5361 In Touch(最短路+并查集)
- HDU 5361 In Touch(最短路 + 线段树)
- hdu 5361 In Touch 最短路(set+搜索实现)
- HDU 5360 - In Touch(最短路)
- HDOJ 5361 In Touch dijkstra最短路
- HDU5361 In Touch(线段树 + 最短路)
- HDU 5361 In Touch(并查集实现区间删除)
- hdu 5124(区间更新,区间最值)
- HDU 5361 In Touch
- HDU 5361 In Touch
- HDU 3339 In Action 解题报告(最短路+背包)
- HDU 3339 In Action(最短路+背包)
- hdu 3339 In Action(最短路+01背包)
- HDU 3339 In Action(最短路+DP)
- HDU 3339 In Action(最短路+01背包)
- HDU 2795 单点更新 + 区间最值
- hdu In Action-最短路+01背包
- 【JavaScript】--概述
- Codeforces 567B Berland National Library
- Sublime 在win上搭建C++环境
- Ray Wenderlich的swift教程01--推荐资料
- springAOP
- HDU 5361 In Touch (2015 多校6 1009 最短路 + 区间更新)
- JAVA Fork/Join 框架
- eclipse连接mysql
- MAC 使用 brew 安装 git
- js生成UUID
- Ubuntu 14.04 /etc/default/grub文件
- Java读取Properties文件的六种方法
- java.util.regex.PatternSyntaxException
- 把数转换成length位的二进制字符串