题意:

有\(n(1 \leq n \leq 10^5)\)个点,\(q(1 \leq q \leq 10^5)\)条路和起点\(s\)

路有三种类型:

  • 从点\(v\)到点\(u\)需要花费\(w\)
  • 从点\(v\)到区间\([l,r]\)中的点花费为\(w\)
  • 从区间\([l,r]\)中的点到点\(v\)花费为\(w\)

求起点到各个点的最少花费

分析:

如下图,构建两颗线段树,边的花费都为\(0\)

对于第一种路直接加边即可

对于第二种路,添加从\(v\)到上面线段树对应区间中的点的边

对于第三种路,添加从下面线段树对应区间中的点到\(v\)的边



最后直接跑最短路

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <map>
  5. #include <set>
  6. #include <vector>
  7. #include <iostream>
  8. #include <string>
  9. #include <queue>
  10. using namespace std;
  11. #define REP(i, a, b) for(int i = a; i < b; i++)
  12. #define PER(i, a, b) for(int i = b - 1; i >= a; i--)
  13. #define SZ(a) ((int)a.size())
  14. #define MP make_pair
  15. #define PB push_back
  16. #define EB emplace_back
  17. #define ALL(a) a.begin(), a.end()
  18. typedef long long LL;
  19. typedef pair<LL, int> PII;
  20. const int maxn = 100000 + 10;
  21. int n, q, s;
  22. struct Edge {
  23. int v, w, nxt;
  24. Edge() {}
  25. Edge(int v, int w, int nxt): v(v), w(w), nxt(nxt) {}
  26. };
  27. int ecnt, head[maxn * 9];
  28. Edge edges[maxn * 36];
  29. void AddEdge(int u, int v, int w) {
  30. printf("%d->%d, w = %d\n", u, v, w);
  31. edges[ecnt] = Edge(v, w, head[u]);
  32. head[u] = ecnt++;
  33. }
  34. int tot, T[2][maxn << 2];
  35. void build(int t, int o, int L, int R) {
  36. T[t][o] = ++tot;
  37. if(L == R) {
  38. if(0 == t) AddEdge(T[t][o], L, 0);
  39. else AddEdge(L, T[t][o], 0);
  40. return;
  41. }
  42. int M = (L + R) / 2;
  43. build(t, o<<1, L, M);
  44. build(t, o<<1|1, M+1, R);
  45. if(0 == t) {
  46. AddEdge(T[t][o], T[t][o<<1], 0);
  47. AddEdge(T[t][o], T[t][o<<1|1], 0);
  48. } else {
  49. AddEdge(T[t][o<<1], T[t][o], 0);
  50. AddEdge(T[t][o<<1|1], T[t][o], 0);
  51. }
  52. }
  53. int type, v, qL, qR, w;
  54. void update(int o, int L, int R) {
  55. if(qL <= L && R <= qR) {
  56. if(0 == type) AddEdge(v, T[type][o], w);
  57. else AddEdge(T[type][o], v, w);
  58. return;
  59. }
  60. int M = (L + R) / 2;
  61. if(qL <= M) update(o<<1, L, M);
  62. if(qR > M) update(o<<1|1, M+1, R);
  63. }
  64. const LL INF = 0x3f3f3f3f3f3f3f3f;
  65. bool vis[maxn * 9];
  66. LL d[maxn * 9];
  67. priority_queue<PII, vector<PII>, greater<PII> > Q;
  68. void dijkstra() {
  69. memset(d, 0x3f, sizeof(d));
  70. d[s] = 0;
  71. Q.emplace(0, s);
  72. while(!Q.empty()) {
  73. PII t = Q.top(); Q.pop();
  74. int& u = t.second;
  75. if(vis[u]) continue;
  76. vis[u] = true;
  77. for(int i = head[u]; ~i; i = edges[i].nxt) {
  78. int& v = edges[i].v;
  79. int& w = edges[i].w;
  80. if(d[v] > d[u] + w) {
  81. d[v] = d[u] + w;
  82. Q.emplace(d[v], v);
  83. }
  84. }
  85. }
  86. }
  87. int main() {
  88. scanf("%d%d%d", &n, &q, &s);
  89. memset(head, -1, sizeof(head));
  90. tot = n;
  91. REP(t, 0, 2) build(t, 1, 1, n);
  92. while(q--) {
  93. scanf("%d%d%d", &type, &v, &qL);
  94. if(type == 1) {
  95. scanf("%d", &w);
  96. AddEdge(v, qL, w);
  97. } else {
  98. type -= 2;
  99. scanf("%d%d", &qR, &w);
  100. update(1, 1, n);
  101. }
  102. }
  103. dijkstra();
  104. REP(i, 1, n + 1) printf("%lld ", d[i] == INF ? -1 : d[i]);
  105. printf("\n");
  106. return 0;
  107. }

Codeforces 787D Legacy 线段树 最短路的更多相关文章

  1. Codeforces 787D. Legacy 线段树建模+最短路

    D. Legacy time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  2. codeforces 787D - Legacy 线段树优化建图,最短路

    题意: 有n个点,q个询问, 每次询问有一种操作. 操作1:u→[l,r](即u到l,l+1,l+2,...,r距离均为w)的距离为w: 操作2:[l,r]→u的距离为w 操作3:u到v的距离为w 最 ...

  3. Codeforces.786B.Legacy(线段树优化建图 最短路Dijkstra)

    题目链接 \(Description\) 有\(n\)个点.你有\(Q\)种项目可以选择(边都是有向边,每次给定\(t,u,v/lr,w\)): t==1,建一条\(u\to v\)的边,花费\(w\ ...

  4. CodeForces - 786B Legacy (线段树+DIjkstra+思维)

    题意:给N个点和Q条选项,有三种类型的选项:1.从u到v花费w修建一条路:2.从u到下标区间为[L,R]的点花费w修建一条路; 3.从下标区间为[L,R]的点到u花费w修建一条路. 然后求起点s到其余 ...

  5. Codeforces 786B. Legacy 线段树+spfa

    题目大意: 给定一个\(n\)的点的图.求\(s\)到所有点的最短路 边的给定方式有三种: \(u \to v\) \(u \to [l,r]\) \([l,r] \to v\) 设\(q\)为给定边 ...

  6. 786B - Legacy(线段树 + 最短路)线段树优化建图

    题意: 就是给定一张n nn个点的图,求源点s ss到每个点的单源最短路.这张图共有q组边,连边方式有3种: a→b ,边权为w的单向边:a→[l,r] ,即a到连续区间[l,r]中的每一个点都有一条 ...

  7. Codeforces Round #406 (Div. 1) B. Legacy 线段树建图跑最短路

    B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...

  8. 【转】Codeforces Round #406 (Div. 1) B. Legacy 线段树建图&&最短路

    B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...

  9. Codeforces Round #406 (Div. 2) D. Legacy 线段树建模+最短路

    D. Legacy time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

随机推荐

  1. 用SQL将数字转换为中文数字

    IF OBJECT_ID('fn_GetChnNum') IS NOT NULL BEGIN DROP FUNCTION dbo.fn_GetChnNum; END; GO CREATE FUNCTI ...

  2. Linux读取NTFS类型数据盘

    Windows的文件系统通常使用NTFS或者FAT32格式,而Linux的文件系统格式通常是EXT系列,请参考下面方法: 1) 在Linux系统上使用以下命令安装ntfsprogs软件使得Linux能 ...

  3. 在C++Builder中定义事件的实现方法

    ++Builder是由Borland公司推出的一款可视化集成开发工具.C++Builder的集成开发环境(IDE)提供了一系列可视化快速应用程序开发(RAD)工具,让程序员可以很轻松地建立和管理自己的 ...

  4. TP5.1:数据库的增删改查操作(基于面向对象操作)

    我们现实中对数据库的增删改查操作,都是使用模型类进行操作的(表名::),也就是面向对象操作,只有底层的代码用的是数据库操作(Db::table('表名')) 下面我将贴出模型类进行的增删改查操作,通过 ...

  5. mysql语句的相关操作整理

    事实证明,如果不经常跟代码,语句打交道,人家可是会翻脸不认人的,大脑也会觉得一脸懵逼,不知道做错了啥,这次长点记性了,把语句整理出来,不仅加强对sql语句的记忆,还能有个笔记,以后大脑懵逼了还能回来看 ...

  6. 《反脆弱》:软件业现成的鲁棒性(Robust)换了个说法变成了作者的发明,按作者的理论推导出许多可笑愚蠢的原则来

    本书作者名气比较大,写过<黑天鹅><随机漫步的傻瓜>等书,据称专门研究不确定度性.本书是他以前的书的内容的延续. 所谓的反脆弱,其实软件业有现成的名词鲁棒性(Robust)就是 ...

  7. 如何用代码的方式取出SAP C4C销售订单创建后所有业务伙伴的数据

    比如我创建了一个Sales Order(销售订单)后,如何用代码的方式取出这些通过SAP Partner determination自动填充的Involved Parties信息呢? 一种方法可以使用 ...

  8. MongoDB在MFC下使用C++驱动编译错误的解决

    .post p{text-indent: 2em;} 今天使用MongoDB的C++驱动,在编译连接的时候一直出现错误,显示的string_data.h下93行max宏的问题,可视其本身并不是调用ma ...

  9. P1725 琪露诺

    P1725 琪露诺 单调队列优化dp 对于不是常数转移的dp转移,我们都可以考虑单调队列转移 然而我们要把数组开大 #include<cstdio> #include<algorit ...

  10. git常用命令(二)

    一. Git 常用命令速查 git branch 查看本地所有分支git status 查看当前状态 git commit 提交 git branch -a 查看所有的分支git branch -r ...