HDU 5361 In Touch (2015 多校6 1009 最短路 + 区间更新)
2015-08-07 11:01
344 查看
题目: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到该点的最短路径。(思路来源队友)
代码:
题意:最短路,求源点到所有点的最短距离。但与普通最短路不同的是,给出的边是某点到区间[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 | 1 const 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 ; int rig ; long long c ; 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; }
相关文章推荐
- Ray Wenderlich的swift教程01--推荐资料
- WAI-ARIA无障碍网页应用
- C++ AMP 介绍(两)
- JAVA web四个属性的范围汇总
- android 可拖动按钮
- 详解 CSS 属性 - 伪类和伪元素的区别
- Linux 安装Git Server
- HDU4463-Outlets
- [Android Studio] Gradle fails to resolve dependencies in Android Studio
- iOS开发_UIWebView加载本地html
- 【linux高级程序设计】(第十五章)UDP网络编程应用 5
- uva 10887 Concatenation of Languages
- c++ STL中的set容器
- mybatis源码分析
- 想成为程序员,学不会编程是自己笨吗?
- setValue: forKeyPath:
- 我是如何自学编程的——“3遍读书法”
- Key Set(找规律+组合数学+快速幂)
- 【机房收费系统】 之 上下机
- Android Fragment 真正的完全解析(上)