首先用Dijkstra做出最短路生成树,设dis[p]为1到p点的最短路长度

对于一条不在生成树上的边u -> v,不妨设fa为u、v的lca

则一fa到v的路径上的任意点x都可以由u达到,走的方式是1 -> fa -> u -> v -> x,dis'[x] = dis[u] + dis(u, v) + dis[v] - dis[x]

于是可以用dis[u] + dis(u, v) + dis[v]更新fa到v的路径上的所有点

链剖一下,线段树lazytag就好了,连pushdown都不需要

  1. /**************************************************************
  2. Problem: 1576
  3. User: rausen
  4. Language: C++
  5. Result: Accepted
  6. Time:2276 ms
  7. Memory:16636 kb
  8. ****************************************************************/
  9.  
  10. #include <cstdio>
  11. #include <algorithm>
  12. #include <queue>
  13.  
  14. using namespace std;
  15. const int N = 1e5 + ;
  16. const int M = 2e5 + ;
  17. const int inf = 1e9;
  18.  
  19. struct edge {
  20. int next, to, v, vis;
  21. edge(int _n = , int _t = , int _v = , int __v = ) : next(_n), to(_t), v(_v), vis(__v) {}
  22. } e[M << ];
  23.  
  24. struct heap_node {
  25. int v, e, to;
  26. heap_node(int _v = , int _e = , int _t = ) : v(_v), e(_e), to(_t) {}
  27.  
  28. inline bool operator < (const heap_node &p) const {
  29. return v > p.v;
  30. }
  31. };
  32.  
  33. struct tree_node {
  34. int fa, sz, dep;
  35. int top, son, e;
  36. int w;
  37. } tr[N];
  38.  
  39. struct seg_node {
  40. seg_node *ls, *rs;
  41. int mn;
  42. } *seg_root, *seg_null, mempool[N << ], *cnt_seg = mempool;
  43.  
  44. int n, m, cnt_q;
  45. int first[N], tot = ;
  46. int dis[N];
  47. priority_queue <heap_node> h;
  48.  
  49. inline int read() {
  50. static int x;
  51. static char ch;
  52. x = , ch = getchar();
  53. while (ch < '' || '' < ch)
  54. ch = getchar();
  55. while ('' <= ch && ch <= '') {
  56. x = x * + ch - '';
  57. ch = getchar();
  58. }
  59. return x;
  60. }
  61.  
  62. inline void Add_Edges(int x, int y, int v) {
  63. e[++tot] = edge(first[x], y, v), first[x] = tot;
  64. e[++tot] = edge(first[y], x, v), first[y] = tot;
  65. }
  66.  
  67. inline void add_to_heap(int p) {
  68. static int x;
  69. for (x = first[p]; x; x = e[x].next)
  70. if (dis[e[x].to] == inf)
  71. h.push(heap_node(e[x].v + dis[p], x, e[x].to));
  72. }
  73.  
  74. void Dijkstra(int S) {
  75. int p;
  76. for (p = ; p <= n; ++p) dis[p] = inf;
  77. while (!h.empty()) h.pop();
  78. dis[S] = , add_to_heap(S);
  79. while (!h.empty()) {
  80. if (dis[h.top().to] != inf) {
  81. h.pop();
  82. continue;
  83. }
  84. p = h.top().to;
  85. dis[p] = h.top().v, e[tr[p].e = h.top().e].vis = ;
  86. h.pop(), add_to_heap(p);
  87. }
  88. }
  89.  
  90. #define y e[x].to
  91. #define Son tr[p].son
  92. void dfs(int p) {
  93. int x;
  94. tr[p].sz = ;
  95. for (x = first[p]; x; x = e[x].next)
  96. if (tr[y].e == x) {
  97. tr[y].dep = tr[p].dep + ;
  98. dfs(y);
  99. tr[p].sz += tr[y].sz;
  100. if (Son == || tr[y].sz > tr[Son].sz) Son = y;
  101. }
  102. }
  103.  
  104. void DFS(int p) {
  105. int x;
  106. tr[p].w = ++cnt_q;
  107. if (Son)
  108. tr[Son].top = tr[p].top, DFS(Son);
  109. for (x = first[p]; x; x = e[x].next)
  110. if (y != Son && tr[y].e == x)
  111. tr[y].top = y, DFS(y);
  112. }
  113. #undef y
  114. #undef Son
  115.  
  116. #define mid (l + r >> 1)
  117. #define Ls p -> ls
  118. #define Rs p -> rs
  119. #define Mn p -> mn
  120. inline void seg_make_null(seg_node *&p) {
  121. p = cnt_seg, Ls = Rs = p, Mn = inf;
  122. }
  123.  
  124. inline void seg_new(seg_node *&p) {
  125. p = ++cnt_seg, *p = *seg_null;
  126. }
  127.  
  128. void seg_build(seg_node *&p, int l, int r) {
  129. seg_new(p);
  130. if (l == r) return;
  131. seg_build(Ls, l, mid), seg_build(Rs, mid + , r);
  132. }
  133.  
  134. void seg_modify(seg_node *p, int l, int r, int L, int R, int v) {
  135. if (L <= l && r <= R) {
  136. Mn = min(Mn, v);
  137. return;
  138. }
  139. if (L <= mid) seg_modify(Ls, l, mid, L, R, v);
  140. if (mid + <= R) seg_modify(Rs, mid + , r, L, R, v);
  141. }
  142.  
  143. int seg_query(seg_node *p, int l, int r, int pos) {
  144. if (l == r) return Mn;
  145. return min(Mn, pos <= mid ? seg_query(Ls, l, mid, pos) : seg_query(Rs, mid + , r, pos));
  146. }
  147. #undef mid
  148. #undef Ls
  149. #undef Rs
  150. #undef Mn
  151.  
  152. int get_lca(int x, int y) {
  153. while (tr[x].top != tr[y].top) {
  154. if (tr[tr[x].top].dep < tr[tr[y].top].dep) swap(x, y);
  155. x = tr[tr[x].top].fa;
  156. }
  157. if (tr[x].dep < tr[y].dep) swap(x, y);
  158. return y;
  159. }
  160.  
  161. void work_modify(int x, int fa, int v) {
  162. while (tr[x].top != tr[fa].top) {
  163. seg_modify(seg_root, , n, tr[tr[x].top].w, tr[x].w, v);
  164. x = tr[tr[x].top].fa;
  165. }
  166. seg_modify(seg_root, , n, tr[fa].w + , tr[x].w, v);
  167. }
  168.  
  169. int main() {
  170. int i, x, y, z, fa, tmp;
  171. n = read(), m = read();
  172. for (i = ; i <= m; ++i) {
  173. x = read(), y = read(), z = read();
  174. Add_Edges(x, y, z);
  175. }
  176. Dijkstra();
  177. for (i = ; i <= n; ++i)
  178. tr[i].fa = e[tr[i].e ^ ].to;
  179. dfs();
  180. tr[].top = , DFS();
  181. seg_make_null(seg_null);
  182. seg_build(seg_root, , n);
  183. #define y e[x].to
  184. for (i = ; i <= n; ++i)
  185. for (x = first[i]; x; x = e[x].next)
  186. if (!e[x].vis) work_modify(y, get_lca(i, y), dis[i] + dis[y] + e[x].v);
  187. #undef y
  188. for (i = ; i <= n; ++i) {
  189. tmp = seg_query(seg_root, , n, tr[i].w);
  190. printf("%d\n", tmp == inf ? - : tmp - dis[i]);
  191. }
  192. return ;
  193. }

BZOJ1576 [Usaco2009 Jan]安全路经Travel的更多相关文章

  1. 【思维题 并查集 图论】bzoj1576: [Usaco2009 Jan]安全路经Travel

    有趣的思考题 Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第 ...

  2. BZOJ1576: [Usaco2009 Jan]安全路经Travel(树链剖分)

    Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第i行包含一个数 ...

  3. BZOJ1576: [Usaco2009 Jan]安全路经Travel(最短路 并查集)

    题意 给你一张无向图,保证从1号点到每个点的最短路唯一.对于每个点求出删掉号点到它的最短路上的最后一条边(就是这条路径上与他自己相连的那条边)后1号点到它的最短路的长度 Sol emmm,考场上想了个 ...

  4. [BZOJ1576] [Usaco2009 Jan]安全路经Travel(堆优化dijk + (并查集 || 树剖))

    传送门 蒟蒻我原本还想着跑两边spfa,发现不行,就gg了. 首先这道题卡spfa,所以需要用堆优化的dijkstra求出最短路径 因为题目中说了,保证最短路径有且只有一条,所以可以通过dfs求出最短 ...

  5. 【BZOJ1576】[Usaco2009 Jan]安全路经Travel 最短路+并查集

    [BZOJ1576][Usaco2009 Jan]安全路经Travel Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, ...

  6. bzoj 1576: [Usaco2009 Jan]安全路经Travel 树链剖分

    1576: [Usaco2009 Jan]安全路经Travel Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 665  Solved: 227[Sub ...

  7. [Usaco2009 Jan]安全路经Travel BZOJ1576 Dijkstra+树链剖分+线段树

    分析: Dijkstra求最短路树,在最短路树上进行操作,详情可见上一篇博客:http://www.cnblogs.com/Winniechen/p/9042937.html 我觉得这个东西不压行写出 ...

  8. bzoj 1576 [Usaco2009 Jan]安全路经Travel(树链剖分,线段树)

    [题意] 给定一个无向图,找到1-i所有的次短路经,要求与最短路径的最后一条边不重叠. [思路] 首先用dijkstra算法构造以1为根的最短路树. 将一条无向边看作两条有向边,考察一条不在最短路树上 ...

  9. bzoj 1576: [Usaco2009 Jan]安全路经Travel——并查集+dijkstra

    Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第i行包含一个数 ...

随机推荐

  1. NS_ASSUME_NONNULL_BEGIN,NS_ASSUME_NONNULL_END

    Nonnull区域设置(Audited Regions) 如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事.苹果为了减轻我们的工作量,专门提供了两个宏:NS_AS ...

  2. 纯js写验证码

    <html> <head> <meta name="viewport" content="width=device-width" ...

  3. FLASH CC 2015 CANVAS (二)html中写JS调用flash中的元件、函数、变量

    注意 此贴 为个人边“开荒”边写,所以不保证就是最佳做法,也难免有错误! 正式教程会在后续开始更新 当你导出第一个canvas后,你会在保存fla的文件夹里 (每个项目默认位置)看到 如下文件,(请先 ...

  4. ubuntu 安装遇到黑屏

    1.安装了ubuntu之后,进入登录页面,然后用输入密码后就黑屏了,按ctrl+alt+f1都没用,也进不去命令界面,查找资料后发现是必须在虚拟机->设置->硬件->显示器,上把加速 ...

  5. compile,build和execute的区别

    一个c程序的生成要经历以下步骤: 1.编写文本代码,生成c或cpp文件,这时候它还是文本的: 2.编译,就是compile,由c编译程序对你写的代码进行词法和句法分析,发现并报告错误,有错时编译不能通 ...

  6. linux install sublime_text3

    ubuntu & debian: (baidu or google) 1). download ***.deb to install inux系统下怎么安装.deb文件? deb 是 ubun ...

  7. 图形处理的api

      [1]旋转      public class MainActivity extends Activity { private float degrees;// 图片旋转的角度 @Override ...

  8. Delphi 过程与函数

    注:该内容整理自以下链接. http://chanlei001.blog.163.com/blog/static/340306642011111615445266/ delphi 过程以保留字proc ...

  9. iOS开发之 xcode6 APP 打包提交审核详细步骤

    一. 在xcode6.1和ios10.10.1环境下实现app发布 http://blog.csdn.net/mad1989/article/details/8167529 http://jingya ...

  10. FATAL ha.BootstrapStandby: Unable to fetch namespace information from active NN at ***

    This problem (Unable to fetch namespace information from active NN) occurs, because the active namen ...