博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF786B Legacy
阅读量:5339 次
发布时间:2019-06-15

本文共 2485 字,大约阅读时间需要 8 分钟。

给定一张有向图,有三种边:

  1. \(u\to v\) ,边权为 \(w\)
  2. \(u\to [l,\ r]\) ,边权为 \(w\)
  3. \([l,\ r]\to u\) ,边权为 \(w\)

\(n,\ m\leq10^5,\ w\leq10^9\)

线段树优化建图,最短路


线段树优化建图板子题,注意空间大小

由于有 \(n\log n\) 条边, 且普通 dijkstra 时间复杂度为 \(O(m\log n)\)

所以时间复杂度 \(O(n\log^2 n)\)

代码

#include 
using namespace std;#define mid ((l + r) >> 1)#define lson ls[k], l, mid#define rson rs[k], mid + 1, rtypedef long long ll;typedef pair
pii;const int maxn = 1e5 + 10, maxm = maxn << 3;ll dis[maxm];int n, m, s, tot, rt_i, rt_o, h[maxm], ls[maxm], rs[maxm];struct edges { int nxt, to, w; edges() {} edges(int x, int y, int z) : nxt(x), to(y), w(z) {}} e[maxn * 30];void addline(int u, int v, int w) { static int cnt; e[++cnt] = edges(h[u], v, w), h[u] = cnt;}void build_i(int &k, int l, int r) { k = ++tot; if (l == r) { addline(k, l, 0); return; } build_i(lson), build_i(rson); addline(k, ls[k], 0), addline(k, rs[k], 0);}void build_o(int &k, int l, int r) { k = ++tot; if (l == r) { addline(l, k, 0); return; } build_o(lson), build_o(rson); addline(ls[k], k, 0), addline(rs[k], k, 0);}void ins_i(int k, int l, int r, int ql, int qr, int u, int x) { if (ql <= l && r <= qr) { addline(u, k, x); return; } if (ql <= mid) ins_i(lson, ql, qr, u, x); if (qr > mid) ins_i(rson, ql, qr, u, x);}void ins_o(int k, int l, int r, int ql, int qr, int u, int x) { if (ql <= l && r <= qr) { addline(k, u, x); return; } if (ql <= mid) ins_o(lson, ql, qr, u, x); if (qr > mid) ins_o(rson, ql, qr, u, x);}int main() { scanf("%d %d %d", &n, &m, &s); tot = n; build_i(rt_i, 1, n); build_o(rt_o, 1, n); for (int i = 1; i <= m; i++) { int op, u, l, r, w; scanf("%d %d %d %d", &op, &u, &l, &r); if (op == 1) { addline(u, l, r); } else if (op == 2) { scanf("%d", &w); ins_i(rt_i, 1, n, l, r, u, w); } else { scanf("%d", &w); ins_o(rt_o, 1, n, l, r, u, w); } } static priority_queue
, greater
> Q; memset(dis, 0x3f, sizeof dis); dis[s] = 0, Q.push(pii(0, s)); while (!Q.empty()) { pii p = Q.top(); int u = p.second; Q.pop(); if (dis[u] < p.first) continue; for (int i = h[u]; i; i = e[i].nxt) { int v = e[i].to; if (dis[v] > dis[u] + e[i].w) { dis[v] = dis[u] + e[i].w; Q.push(pii(dis[v], v)); } } } for (int i = 1; i <= n; i++) { printf("%I64d ", dis[i] < 1ll << 60 ? dis[i] : -1); } return 0;}

转载于:https://www.cnblogs.com/Juanzhang/p/10837086.html

你可能感兴趣的文章
关于谷歌浏览器Chrome正在处理请求的问题解决
查看>>
Git核心技术:在Ubuntu下部署Gitolite服务端
查看>>
平面波展开法总结
查看>>
建造者模式
查看>>
ArraySort--冒泡排序、选择排序、插入排序工具类demo
查看>>
composer 安装laravel
查看>>
8-EasyNetQ之Send & Receive
查看>>
Android反编译教程
查看>>
java重写LinkedList
查看>>
zTree节点重叠或者遮挡
查看>>
List<string> 去重复 并且出现次数最多的排前面
查看>>
js日志管理-log4javascript学习小结
查看>>
Android之布局androidmanifest.xml 资源清单 概述
查看>>
How to Find Research Problems
查看>>
Linux用户管理
查看>>
数据库第1,2,3范式学习
查看>>
《Linux内核设计与实现》第四章学习笔记
查看>>
使用iperf测试网络性能
查看>>
struts2入门之准备工作
查看>>
从C语言的弱类型属性说起
查看>>