* 给出一张图
* 每次删掉一条边后求 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[]的点所取到的最小值

#include <bits/stdc++.h>

const int N = 2e5 + ;// oo = 999999999;

#define LL long long

const LL oo = 9e18;

int n, m, S, T;
int Short_path[N], Snum[N], Tnum[N], Id[N], path_js;
bool vis[N];
int head[N], now;
struct Node {int u, v, w, nxt;} G[N << ];
LL dis_s[N], dis_t[N];
LL Minn[N << ], Ans[N]; inline void Add(int u, int v, int w) {
G[++ now].v = v, G[now].w = w, G[now].nxt = head[u], head[u] = now;
} struct Node_ {
int u; LL dis;
bool operator < (const Node_ a) const {
return dis > a.dis;
}
}; std:: priority_queue <Node_> Q; void Dijkstra(int start, LL dis_[]) {
for(int i = ; i <= n; i ++) dis_[i] = oo, vis[i] = ;
Node_ now; now = (Node_) {start, }; dis_[start] = ;
Q.push(now);
while(!Q.empty()) {
Node_ topp = Q.top();
Q.pop();
if(vis[topp.u]) continue;
vis[topp.u] = ;
for(int i = head[topp.u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(dis_[v] > dis_[topp.u] + G[i].w) {
dis_[v] = dis_[topp.u] + G[i].w;
Q.push((Node_) {v, dis_[v]});
}
}
}
} inline void Bfs(int x, LL dis_[], int bel[]) {
std:: queue <int> Q1;
Q1.push(Short_path[x]);
bel[Short_path[x]] = x;
while(!Q1.empty()) {
int topp = Q1.front();
Q1.pop();
for(int i = head[topp]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(!Id[v] && !bel[v] && dis_[v] == dis_[topp] + G[i].w) {
bel[v] = x;
Q1.push(v);
}
}
}
} #define lson jd << 1
#define rson jd << 1 | 1 void Sec_G(int l ,int r, int jd, int x, int y, LL num) {
if(x <= l && r <= y) {
Minn[jd] = std:: min(Minn[jd], (LL)num);
return ;
}
int mid = (l + r) >> ;
if(x <= mid) Sec_G(l, mid, lson, x, y, num);
if(y > mid) Sec_G(mid + , r, rson, x, y, num);
} void Dfs_tree(int l, int r, int jd) {
if(l == r) {
Ans[l] = Minn[jd];
return ;
}
int mid = (l + r) >> ;
Minn[lson] = std:: min(Minn[lson], Minn[jd]);
Minn[rson] = std:: min(Minn[rson], Minn[jd]);
Dfs_tree(l, mid, lson), Dfs_tree(mid + , r, rson);
} #define gc getchar() inline LL read() {
LL x = ; char c = gc;
while(c < '' || c > '') c = gc;
while(c >= '' && c <= '') x = x * + c - '', c = gc;
return x;
} main() {
n = read(), m = read();
for(int i = ; i <= (N << ); i ++) Minn[i] = oo;
for(int i = ; i <= n; i ++) head[i] = -;
for(int i = ; i <= m; i ++) {
int u = read(), v = read(), w = read();
Add(u, v, w), Add(v, u, w);
}
S = read(), T = read();
if(S == T) {
int Q = read();
for(; Q; Q --) puts("");
return ;
}
Dijkstra(S, dis_s);
Dijkstra(T, dis_t);
if(dis_s[T] == oo) {
int Q = read();
for(; Q; Q --) puts("Infinity");
return ;
}
for(int i = S; i != T; i = i) {
Short_path[++ path_js] = i;
Id[i] = path_js;
for(int j = head[i]; ~ j; j = G[j].nxt) {
if(dis_t[i] == G[j].w + dis_t[G[j].v]) {
i = G[j].v; break;
}
}
}
Short_path[path_js + ] = T, Id[T] = path_js + ;
for(int i = ; i <= path_js; i ++) Bfs(i, dis_s, Snum);
for(int i = path_js + ; i >= ; i --) Bfs(i, dis_t, Tnum);
for(int i = ; i <= n; i ++) {
for(int j = head[i]; ~ j; j = G[j].nxt) {
int v = G[j].v;
if(Id[i] && Id[v] && abs(Id[i] - Id[v]) == ) continue;
if(Snum[i] < Tnum[v] && Snum[i] && Tnum[v]) {
Sec_G(, path_js, , Snum[i], Tnum[v] - , dis_s[i] + G[j].w + dis_t[v]);
}
}
}
Dfs_tree(, path_js, );
int Q = read();
for(; Q; Q --) {
int x = read(), y = read();
if(Id[x] > Id[y]) std:: swap(x, y);
if(Id[x] && Id[y] && Id[y] - Id[x] == ) {
if(Ans[Id[x]] == oo) puts("Infinity");
else printf("%lld\n", Ans[Id[x]]);
} else printf("%lld\n", dis_s[T]);
}
return ;
}

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. QT聊天室--重大bug

    发送qqqqqqqqqqqqqqqqqqqqqqq: 发送test

  2. asp.net core-3.应用程序部署到iis

    asp.net core在部署到iis 上的时候,iis服务器要装一个AspNetCoreModule,网站—>模块  具体下载地址可以去网上搜索https://www.nuget.org/pa ...

  3. jacascript 数组

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 数组的增删 第一个数组元素的索引值为 0,第二个索引值为 1,始终递增. 数组可以在头部增加元素arr.u ...

  4. SqlServer用sql语句清理log日志

    原文:SqlServer用sql语句清理log日志 USE[master] ALTER DATABASE [Center] SET RECOVERY SIMPLE WITH NO_WAIT ALTER ...

  5. JS基础_this补充

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. 数据库入门(mySQL):创建数据库

    基于JetBrains DataGrip创建数据库.SQL语句创建数据库 MySQL数据库存储引擎和数据类型 创建数据库表及基本操作 导出数据库.删除数据库.导入数据库 一.基于JetBrains D ...

  7. git remote 使用总结

    使用场景:新建一个git仓储并与远程关联 1.初始化一个新的空的git仓储,并在仓储下做一些改动 mkdir gitDir cd gitDir/ git init touch file git sta ...

  8. MySQL菜鸟入门“秘籍”

    一.MySQL简介 1.什么是数据库 ? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后,数据管理不 ...

  9. linux-2.6.38 IIC驱动框架分析

    在linux-2.6内核中,IIC的驱动程序可以大概分为三部分: (1)IIC核心代码:/drivers/i2c/i2c-core.c IIC核心提供了IIC总线驱动和设备驱动的注册.注销方法和IIC ...

  10. 迭代器 Iterator 是什么?(未完成)Iterator 怎么使用?(未完成)有什么特点?(未完成)

    迭代器 Iterator 是什么?(未完成)Iterator 怎么使用?(未完成)有什么特点?(未完成)