[Wannafly挑战赛2D-Delete]最短路

题目描述

给定一张 n 个点,m 条边的带权有向无环图,同时给定起点 S 和终点 T ,一共有 q 个询问,每次询问删掉某个点和所有与它相连的边之后 S 到 T 的最短路,询问之间互相独立(即删除操作在询问结束之后会立即撤销),如果删了那个点后不存在 S 到 T 的最短路,则输出 −1 。点的编号为 1 到 n 。

输入格式

第一行四个正整数表示 n,m,S,T ,意义如题所述。

接下来 m 行每行三个正整数 x,y,z ,表示有一条 x 到 y 的有向边,权值为 z 。

接下来一行一个正整数 Q 表示询问次数。

最后 Q 行每行一个正整数 k 表示这次询问要删除点 k  。

输出格式

输出 Q 行,每行一个整数表示答案。

样例一

input

6 7 1 5
1 2 2
2 3 4
3 4 3
4 5 5
3 5 9
1 6 10
6 5 13
4
3
4
2
6

output

23
15
23
14

限制与约定

对于 100% 的数据,1≤S,T,x,y,k≤n≤10^5 ;1≤Q≤10^5 ;1≤m≤2×10^5 ;0≤z≤10^9

Solution

题意为:给定一个,多次询问任意删掉一个点之后,S到T的最短路。

首先,这是一个,因此S到T的最短路是可以沿拓扑序DP直接求出的,因此我们不花半点力气,就得到了一个的算法。

现在我们考虑删点对于一个的影响,即之前通过拓扑序求出的拓扑图其中一个点不能通过。

先特判S到T不连通的情况,直接输出-1即可。

现在我们保证了S到T有一条可行路径。考虑拓扑图之外的边对其影响,它们会提供一种可行的方式跨过被删点连向之后的节点,形成最短路的总代价为     ,而这一条路会对在拓扑图中u,v两点之间所有点产生相同的影响。即u,v之间所有点形成的最短路,都能用这一条边形成的路径代替(不保证最短,只保证可行)。

于是问题变成了:一堆边会改变拓扑序中连续的一段区间[l,r]的点的代价,求任意某点的最优代价。区间修改+单点查询,线段树维护最小值即可。

时间复杂度为    。

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se secondusing namespace std;template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=1e9+7;
const ll INF=1ll<<60;
const int MAXN=1e5+500;
/*--------------------------------------------------------------------*/
struct enode{int v; ll c; };
vector<enode> e1[MAXN],e2[MAXN];
int d1[MAXN],d2[MAXN],dfn[MAXN];
ll f1[MAXN],f2[MAXN];
queue<int> que;
inline int read()
{int f=1,x=0; char c=getchar();while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); }return x*f;
}
inline char readc()
{char c=getchar();while (!isalnum(c)) c=getchar();return c;
}
struct Segment_Tree
{struct treenode{int l,r; ll s; } tree[MAXN<<2];void build(int x,int l, int r){tree[x].s=INF;if ((tree[x].l=l)==(tree[x].r=r)) return;int mid=(tree[x].l+tree[x].r)>>1;build(x<<1,l,mid);build(x<<1|1,mid+1,r);}void change(int x,int L,int R,ll val){if (L<=tree[x].l&&tree[x].r<=R) { tree[x].s=min(tree[x].s,val); return; }int mid=(tree[x].l+tree[x].r)>>1;if (L<=mid) change(x<<1,L,R,val);if (mid<R) change(x<<1|1,L,R,val);}ll query(int x,int y){if (tree[x].l==tree[x].r) return tree[x].s;int mid=(tree[x].l+tree[x].r)>>1;if (y<=mid) return min(tree[x].s,query(x<<1,y));else return min(tree[x].s,query(x<<1|1,y));}
} segment;
int main()
{//freopen("shortest.in","r",stdin);//freopen("shortest.out","w",stdout);int n=read(),m=read(),S=read(),T=read();for (int i=1;i<=m;i++){int u=read(),v=read(),c=read();e1[u].push_back((enode){v,c});e2[v].push_back((enode){u,c});d1[v]++; d2[u]++;}int Dfn=0;for (int i=1;i<=n;i++) f1[i]=INF; f1[S]=0;for (int i=1;i<=n;i++) if (d1[i]==0) que.push(i); while (!que.empty()){int q=que.front();dfn[q]=++Dfn;que.pop();for (int i=0;i<e1[q].size();i++){int to=e1[q][i].v,c=e1[q][i].c;d1[to]--;f1[to]=min(f1[to],f1[q]+c);if (d1[to]==0) que.push(to);}}que.push(T);for (int i=1;i<=n;i++) f2[i]=INF; f2[T]=0;for (int i=1;i<=n;i++) if (d2[i]==0) que.push(i);while (!que.empty()){int q=que.front();que.pop();for (int i=0;i<e2[q].size();i++){int to=e2[q][i].v,c=e2[q][i].c;d2[to]--;f2[to]=min(f2[to],f2[q]+c);if (d2[to]==0) que.push(to);}}segment.build(1,1,n);for (int i=1;i<=n;i++) for (int j=0;j<e1[i].size();j++)if (f1[i]!=INF&&f2[e1[i][j].v]!=INF&&dfn[i]+1<dfn[e1[i][j].v]) segment.change(1,dfn[i]+1,dfn[e1[i][j].v]-1,f1[i]+f2[e1[i][j].v]+e1[i][j].c);int Case=read();while (Case--){int x=read();if (f1[x]==INF||f2[x]==INF) printf("%lld\n",f1[T]);else {ll q=segment.query(1,dfn[x]);printf("%lld\n",q==INF?-1:q);}}return 0;
}

[Wannafly挑战赛2D-Delete]最短路相关推荐

  1. Wannafly挑战赛22游记

    Wannafly挑战赛22游记 幸运的人都是相似的,不幸的人各有各的不幸. --题记 A-计数器 题目大意: 有一个计数器,计数器的初始值为\(0\),每次操作你可以把计数器的值加上\(a_1,a_2 ...

  2. Wannafly挑战赛19

    Wannafly挑战赛19 A. 队列Q 需要支持把一个元素移到队首,把一个元素移到队尾,移到队首就直接放到队首前面那个位置,原位置标为0,队尾同理. #include <bits/stdc++ ...

  3. Wannafly挑战赛18

    Wannafly挑战赛18 A. 序列 先考虑暴力,相邻两个树之间乘上给定的三种数,递推出下一个位置填什么,然后再check一下,最后一位是否为1即可.这样时间显然不行,但是给我们一种思路,就是中间的 ...

  4. Wannafly 挑战赛27 题解

    Wannafly 挑战赛27 题目连接 https://www.nowcoder.com/acm/contest/215#question A.灰魔法师 题目 题解 考虑到可能的完全平方数只有4004 ...

  5. Wannafly挑战赛24

    Wannafly挑战赛24 题目连接 https://www.nowcoder.com/acm/contest/186#question A.石子游戏 题解 注意到当石子个数为偶数的时候,每回合都会减 ...

  6. Wannafly挑战赛18B 随机数

    Wannafly挑战赛18B 随机数 设\(f_i\)表示生成\(i\)个数有奇数个1的概率. 那么显而易见的递推式:\(f_i=p(1-f_{i-1})+(1-p)f_{i-1}=(1-2p)f_{ ...

  7. Wannafly挑战赛14 A-直角三棱锥

    Wannafly挑战赛14 A-直角三棱锥 链接:https://www.nowcoder.com/acm/contest/81/A 来源:牛客网 题目描述 在三维空间中,平面 x = 0, y = ...

  8. Wannafly挑战赛27 C蓝魔法师

    链接Wannafly挑战赛27 C蓝魔法师 给出一棵树,求有多少种删边方案,使得删后的图每个连通块大小小于等于\(k\),\(n,k\leq 2*10^3\) 假设我们正在考虑\(i\)这个子树,那么 ...

  9. Wannafly挑战赛26-B 冥土追魂

    地址:https://www.nowcoder.com/acm/contest/212/B 思路:对于行列选取,是选择所有行中的最大值的最小值,当是并不能用贪心来做,例如 2 2 2 7 8 1 9 ...

最新文章

  1. 【PHP】安装 ssh2 模块
  2. ubuntu最基本的软件
  3. python 最小硬币数_Python之动态规划(最少硬币数找零)
  4. 有必要服务器虚拟化吗,服务器虚拟化有必要吗
  5. 以撩妹为例,5分钟让你秒懂深度学习!
  6. python tkinter库函数详解_Python使用tkinter库进行GUI编程中常用事件处理方式汇总
  7. javascript 停止事件冒泡以及阻止默认事件冒泡
  8. 工程师,你的钱究竟从哪来?
  9. spire.pdf系列文章
  10. Java的GUI学习八(键盘码查询器)
  11. paip.java gui swt/jface 最佳实践
  12. (转)嘉信理财再度全面降佣,它会否成为投资界的Amazon?
  13. FTP 文件上传跟下载
  14. web 安全-电脑端口(全部)
  15. Lingo教育版免费申请流程
  16. 如何用LOTO示波器TDR方法测试电线长度?
  17. WIFI智能插座Homekit
  18. shopnc nodejs安装
  19. 【51单片机】十分钟学会定时器中断¹
  20. Front Immunol 复现 | 1. GEO数据下载及sva批次校正(PCA可视化)

热门文章

  1. 拿了年终奖后,发现自己又拖后腿了?对不起,可能事实并没有那么糟糕...
  2. 继Science发文后,Nature也发文评论曹雪涛“误用图片”调查结果
  3. 酸了!第一名+第三名的学霸情侣,分别直博清华、人大…
  4. 你在孩子身上偷的懒,终将会变成最大的遗憾
  5. 实用Python库,这几个你认识不?
  6. linux+4.4+android,Ubuntu 14.04 x64配置Android 4.4 kitkat编译环境的方法
  7. php中怎样表示组合框,php – 如何实现动态组合框选择系统
  8. c语言字符比较思路,C语言讲解思路资料
  9. 机器人等级考试一级教具_全国青少年机器人技术等级考试(一级):基本结构...
  10. 计算机原理试题b,计算机组成原理试题B答案