* 给出一张图
* 每次删掉一条边后求 the shortest path from S to T
* 线段树维护最短路径树
* 具体维护从某点开始偏离最短路而到达 T 的最小距离
* 首先记录下最短路径
* 考虑每一种走法都是 S -> a -> x -> y -> b -> T, 其中 S -> a, b -> T 是最短路上的边
* 把树上的点i能以最短路到达的点标记上Id[i],每个点只标记第一次
* 枚举所有的边
* 对于边(u,v),若u从起点标记到的Id[] < v从终点标记到的 Id[]
* 则线段树区间修改最小值
* 对于每次用意义的询问,只需输出较小Id[]的点所取到的最小值

  1. #include <bits/stdc++.h>
  2.  
  3. const int N = 2e5 + ;// oo = 999999999;
  4.  
  5. #define LL long long
  6.  
  7. const LL oo = 9e18;
  8.  
  9. int n, m, S, T;
  10. int Short_path[N], Snum[N], Tnum[N], Id[N], path_js;
  11. bool vis[N];
  12. int head[N], now;
  13. struct Node {int u, v, w, nxt;} G[N << ];
  14. LL dis_s[N], dis_t[N];
  15. LL Minn[N << ], Ans[N];
  16.  
  17. inline void Add(int u, int v, int w) {
  18. G[++ now].v = v, G[now].w = w, G[now].nxt = head[u], head[u] = now;
  19. }
  20.  
  21. struct Node_ {
  22. int u; LL dis;
  23. bool operator < (const Node_ a) const {
  24. return dis > a.dis;
  25. }
  26. };
  27.  
  28. std:: priority_queue <Node_> Q;
  29.  
  30. void Dijkstra(int start, LL dis_[]) {
  31. for(int i = ; i <= n; i ++) dis_[i] = oo, vis[i] = ;
  32. Node_ now; now = (Node_) {start, }; dis_[start] = ;
  33. Q.push(now);
  34. while(!Q.empty()) {
  35. Node_ topp = Q.top();
  36. Q.pop();
  37. if(vis[topp.u]) continue;
  38. vis[topp.u] = ;
  39. for(int i = head[topp.u]; ~ i; i = G[i].nxt) {
  40. int v = G[i].v;
  41. if(dis_[v] > dis_[topp.u] + G[i].w) {
  42. dis_[v] = dis_[topp.u] + G[i].w;
  43. Q.push((Node_) {v, dis_[v]});
  44. }
  45. }
  46. }
  47. }
  48.  
  49. inline void Bfs(int x, LL dis_[], int bel[]) {
  50. std:: queue <int> Q1;
  51. Q1.push(Short_path[x]);
  52. bel[Short_path[x]] = x;
  53. while(!Q1.empty()) {
  54. int topp = Q1.front();
  55. Q1.pop();
  56. for(int i = head[topp]; ~ i; i = G[i].nxt) {
  57. int v = G[i].v;
  58. if(!Id[v] && !bel[v] && dis_[v] == dis_[topp] + G[i].w) {
  59. bel[v] = x;
  60. Q1.push(v);
  61. }
  62. }
  63. }
  64. }
  65.  
  66. #define lson jd << 1
  67. #define rson jd << 1 | 1
  68.  
  69. void Sec_G(int l ,int r, int jd, int x, int y, LL num) {
  70. if(x <= l && r <= y) {
  71. Minn[jd] = std:: min(Minn[jd], (LL)num);
  72. return ;
  73. }
  74. int mid = (l + r) >> ;
  75. if(x <= mid) Sec_G(l, mid, lson, x, y, num);
  76. if(y > mid) Sec_G(mid + , r, rson, x, y, num);
  77. }
  78.  
  79. void Dfs_tree(int l, int r, int jd) {
  80. if(l == r) {
  81. Ans[l] = Minn[jd];
  82. return ;
  83. }
  84. int mid = (l + r) >> ;
  85. Minn[lson] = std:: min(Minn[lson], Minn[jd]);
  86. Minn[rson] = std:: min(Minn[rson], Minn[jd]);
  87. Dfs_tree(l, mid, lson), Dfs_tree(mid + , r, rson);
  88. }
  89.  
  90. #define gc getchar()
  91.  
  92. inline LL read() {
  93. LL x = ; char c = gc;
  94. while(c < '' || c > '') c = gc;
  95. while(c >= '' && c <= '') x = x * + c - '', c = gc;
  96. return x;
  97. }
  98.  
  99. main() {
  100. n = read(), m = read();
  101. for(int i = ; i <= (N << ); i ++) Minn[i] = oo;
  102. for(int i = ; i <= n; i ++) head[i] = -;
  103. for(int i = ; i <= m; i ++) {
  104. int u = read(), v = read(), w = read();
  105. Add(u, v, w), Add(v, u, w);
  106. }
  107. S = read(), T = read();
  108. if(S == T) {
  109. int Q = read();
  110. for(; Q; Q --) puts("");
  111. return ;
  112. }
  113. Dijkstra(S, dis_s);
  114. Dijkstra(T, dis_t);
  115. if(dis_s[T] == oo) {
  116. int Q = read();
  117. for(; Q; Q --) puts("Infinity");
  118. return ;
  119. }
  120. for(int i = S; i != T; i = i) {
  121. Short_path[++ path_js] = i;
  122. Id[i] = path_js;
  123. for(int j = head[i]; ~ j; j = G[j].nxt) {
  124. if(dis_t[i] == G[j].w + dis_t[G[j].v]) {
  125. i = G[j].v; break;
  126. }
  127. }
  128. }
  129. Short_path[path_js + ] = T, Id[T] = path_js + ;
  130. for(int i = ; i <= path_js; i ++) Bfs(i, dis_s, Snum);
  131. for(int i = path_js + ; i >= ; i --) Bfs(i, dis_t, Tnum);
  132. for(int i = ; i <= n; i ++) {
  133. for(int j = head[i]; ~ j; j = G[j].nxt) {
  134. int v = G[j].v;
  135. if(Id[i] && Id[v] && abs(Id[i] - Id[v]) == ) continue;
  136. if(Snum[i] < Tnum[v] && Snum[i] && Tnum[v]) {
  137. Sec_G(, path_js, , Snum[i], Tnum[v] - , dis_s[i] + G[j].w + dis_t[v]);
  138. }
  139. }
  140. }
  141. Dfs_tree(, path_js, );
  142. int Q = read();
  143. for(; Q; Q --) {
  144. int x = read(), y = read();
  145. if(Id[x] > Id[y]) std:: swap(x, y);
  146. if(Id[x] && Id[y] && Id[y] - Id[x] == ) {
  147. if(Ans[Id[x]] == oo) puts("Infinity");
  148. else printf("%lld\n", Ans[Id[x]]);
  149. } else printf("%lld\n", dis_s[T]);
  150. }
  151. return ;
  152. }

bzoj2725的更多相关文章

  1. 【BZOJ-2725】故乡的梦 Dijsktra + Tarjan + Dinic + BFS + 堆

    2725: [Violet 6]故乡的梦 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 502  Solved: 173[Submit][Status ...

  2. BZOJ2725 : [Violet 6]故乡的梦

    如果S==T,那么答案为0. 如果S与T不连通,那么答案为inf. 否则,S到T的最短路径上至少有一条边. 求出以S为源点的最短路图,是个DAG,随便抓一条S到T的最短路,记为P. 设dpS[x]表示 ...

  3. bzoj4400

    /* * 此题同bzoj2725 * 增加了枚举边的操作 */ #include <bits/stdc++.h> ;// oo = 999999999; #define LL long l ...

随机推荐

  1. asp.net core-14.JWT认证授权 生成 JWT Token

    源码下载 语言组织能力不好 ,看这个 视频 用visual studio code打开文件,运行dotnet watch run 之后在postman里面去访问 拿到Token后

  2. js 监听键盘的enter键

    // js 版本 window.onload=function(){ document.onkeydown=function(ev){ var event=ev ||event if(event.ke ...

  3. Map 集合遍历的4种方法

    Map 集合初始化时,指定集合初始值大小. 说明:HashMap 使用 HashMap(int initialCapacity) 初始化. 正例:initialCapacity = (需要存储的元素个 ...

  4. python练习:函数3

    习题: 用lambda和filter完成下面功能:输出一个列表,列表里面包括:1-100内的所有偶数.(提示:可以用filter,lambda) [ x for x in range(1,101) i ...

  5. c# 163网易发送邮件

    是4.0的,说以添加包是 代码: public class SendEmailInfo { /// <summary> /// 发送邮件 /// </summary> /// ...

  6. vue中使用ts后,父组件获取执行子组件方法报错问题

    一.问题产生背景: 子组件的一个方法: update () { this.$nextTick(() => { this.ul_slots.forEach((ul, cur_slots_index ...

  7. linux服务脚本

    #!/bin/sh ARG=$1 case $ARG in start): nohup /path/program & ;; stop): pkill program ;; restart): ...

  8. Array + two points leetcode.18 - 4Sum

    题面 Given an array nums of n integers and an integer target, are there elements a, b, c, and d in num ...

  9. shell code

  10. 《数据结构与算法之美》 <04>链表(上):如何实现LRU缓存淘汰算法?

    今天我们来聊聊“链表(Linked list)”这个数据结构.学习链表有什么用呢?为了回答这个问题,我们先来讨论一个经典的链表应用场景,那就是 LRU 缓存淘汰算法. 缓存是一种提高数据读取性能的技术 ...