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

本文共 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

你可能感兴趣的文章
自己实现的简易的knn算法
查看>>
连载22:软件体系设计新方向:数学抽象、设计模式、系统架构与方案设计(简化版)(袁晓河著)...
查看>>
手机上怎么实现PDF文件转换成Excel表格
查看>>
ServiceComb实战
查看>>
0011-如何在Hive & Impala中使用UDF
查看>>
Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
查看>>
window 2008 下 安装域管理并且控制qq和usb
查看>>
WCF SOA服务应用
查看>>
centos 6的网卡坑
查看>>
Unity性能优化-内存优化
查看>>
oracle 内存二 SGA
查看>>
跟我一起学QT5:布局管理
查看>>
HTTP 之 一次完整的http请求处理过程
查看>>
LVS 之 高可用性
查看>>
Java冒泡排序之我见
查看>>
KVM虚拟化技术 笔记(一)
查看>>
storm 一个报错 Async loop died! & reconnect
查看>>
钱的重要性
查看>>
[转载]HTTP POST GET 本质区别详解
查看>>
助力51下载中心,分享优秀资源
查看>>