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

[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

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

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

 

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

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

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

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

时间复杂度为  O(nlgn)  。

 

#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;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/315871.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET Core MVC 视图

ASP.NET Core MVC中视图的知识和ASP.NET MVC有很多相似之处&#xff0c;学习难度较低。以下内容主要体现了编程中模块化的思想&#xff0c;模块化才应是我们关注的重点。布局用于提供各个页面所需的公共部分&#xff0c;如&#xff1a;菜单、页头、页尾等。在ASP.NET Core中默认…

CF993E Nikita and Order Statistics

CF993E Nikita and Order Statistics 题意&#xff1a; 给你一个数组 a1∼na_{1 \sim n}a1∼n​&#xff0c;对于 k0∼nk 0 \sim nk0∼n&#xff0c;求出有多少个数组上的区间满足&#xff1a;区间内恰好有 k 个数比 x 小。 x 为一个给定的数。 n≤2105n \le 2 \times 10^5n…

ASP.NET Core 通过 Microsoft.DotNet.Watcher.Tools 实现热部署

之前开发前端的时候&#xff0c;webpack 会有热更新工具&#xff0c;在修改了代码之后&#xff0c;自动将代码编译&#xff0c;实时展现到页面上&#xff0c;给开发带来了极大的方便。Java也可以通过第三方插件JRebel实现热部署&#xff0c;不用频繁的重启Tomcat。微软官方也为…

P3825 [NOI2017]游戏

P3825 [NOI2017]游戏 题目描述 小 L 计划进行n场游戏&#xff0c;每场游戏使用一张地图&#xff0c;小 L 会选择一辆车在该地图上完成游戏。 小 L 的赛车有三辆&#xff0c;分别用大写字母A、B、C表示。地图一共有四种&#xff0c;分别用小写字母x、a、b、c表示。其中&#x…

事关SuperSocket发布,寻找YangFan哥哥

SuperSocket近日发布了2.0的第一个预览版《SuperSocket 2.0 Preview1 发布&#xff0c;.NET Socket服务器框架》&#xff0c;在NuGet上以一个包含数个SuperSocket程序集的大包的形式发布。https://www.nuget.org/packages/SuperSocket/2.0.0-preview1我原意以独立小包的形式发布…

P3321 [SDOI2015]序列统计(未解决)

P3321 [SDOI2015]序列统计 题意&#xff1a; 题解&#xff1a; 参考题解&#xff1a; 题解 P3321 【[SDOI2015]序列统计】 【LG3321】[SDOI2015]序列统计 神仙题。。学透再补 代码&#xff1a;

P1963 [NOI2009]变换序列

题目描述 不想水字&#xff0c;详见某谷&#xff1a;P1963 [NOI2009]变换序列 solution 其实 的计算就类似于环上的距离。 对于每一个 都可能有两种位置选择&#xff1a;&#xff0c; 。 所以把它们分别连边&#xff0c;二分图上匈牙利算法求完美匹配即可。 #include&…

一次 .NET Core 中玩锁的经历:ManualResetEventSlim, SemaphoreSlim

最近同事对 .net core memcached 缓存客户端 EnyimMemcachedCore 进行了高并发下的压力测试&#xff0c;发现在 linux 上高并发下使用 async 异步方法读取缓存数据会出现大量失败的情况&#xff0c;比如在一次测试中&#xff0c;100万次读取缓存&#xff0c;只有12次成功&…

BZOJ4589. Hard Nim

BZOJ4589. Hard Nim 题意&#xff1a; Claris和NanoApe在玩石子游戏&#xff0c;他们有n堆石子&#xff0c;规则如下&#xff1a; Claris和NanoApe两个人轮流拿石子&#xff0c;Claris先拿。每次只能从一堆中取若干个&#xff0c;可将一堆全取走&#xff0c;但不可不取&…

P2825 [HEOI2016/TJOI2016]游戏

题目描述 详见 P2825 [HEOI2016/TJOI2016]游戏。 solution 套路题。 一般思路是行列建点跑二分图最大匹配。 此题中的#会分隔行列&#xff0c;因此我们把每行的极大联通块设为点&#xff0c;列同理建点。 再对于每个*对应的行的极大联通块与列的最大联通块编号连边&…

P3033 [USACO11NOV]牛的障碍Cow Steeplechase

P3033 [USACO11NOV]牛的障碍Cow Steeplechase 题目描述 详见&#xff1a;P3033 [USACO11NOV]牛的障碍Cow Steeplechase solution 裸题。 对于每一对相交的线段&#xff0c;连一条边&#xff0c;表示这一对线段不能都取。 显然这样会建立一个二分图&#xff08;横的线段不…

Tree Cutting HDU - 5909

Tree Cutting HDU - 5909 题意&#xff1a; 一个无根树&#xff0c;n个点&#xff0c;n-1条边&#xff0c;每个节点有一个权值&#xff0c;一棵树的权值就是其节点(包含本身及其子节点)的权值的异或和&#xff1b;求价值为[0,m)的树有多少颗&#xff1f;(所谓的树其实就是原连…

Redis作者antirez:开源维护者的挣扎

这两天&#xff0c;一篇名为《开源维护者的挣扎》的文章被迅速顶至 Hacker News 首页&#xff0c;这是 Redis 作者 antirez 发布的最新博客。几个月前&#xff0c;一名开源项目的维护者向 antirez 发邮件&#xff0c;倾诉自己苦心维护项目多年&#xff0c;这或多或少带来了一些…

CF662C Binary Table

CF662C Binary Table 题意&#xff1a; 有一个 n 行 m 列的表格&#xff0c;每个元素都是 0/1 &#xff0c;每次操作可以选择一行或一列&#xff0c;把 0/1 翻转&#xff0c;即把 0 换为 1 &#xff0c;把 1 换为 0 。请问经过若干次操作后&#xff0c;表格中最少有多少个 1 …

P4111 [HEOI2015]小Z的房间

P4111 [HEOI2015]小Z的房间 题目描述 详见&#xff1a;P4111 [HEOI2015]小Z的房间 solution Matrix-Tree裸题。 题意为求一个有障碍的网格图的生成树个数。 因此对于每一个点向左边和上面的节点连边&#xff0c;Matrix-Tree定理求解生成树个数即可。 #include<bits/s…

黑科技抢先尝(续) - Windows terminal中WSL Linux 终端的极简美化指南

之前&#xff0c;本人写了两篇文章 黑科技抢先尝 | Windows全新终端初体验(附代码Build全过程) 和 程会玩 | 无需自行编译也能玩转 Windows Terminal&#xff0c;介绍了玩转Windows terminal的两种方式。今天这篇文章&#xff0c;主要介绍如何美化 Windows terminal 中 WSL 的 …

P3203 [HNOI2010]弹飞绵羊

P3203 [HNOI2010]弹飞绵羊 题目描述 详见&#xff1a;P3203 [HNOI2010]弹飞绵羊 solution 这是一道LCT的裸题。 但是我并不想用LCT解决此题&#xff08;In fact 是不会LCT ~QAQ&#xff09; 于是我们开始大力分块。 考虑把弹跳装置分块&#xff0c;我们每次需要知道在一…

L - Two Ants Gym - 102823L

L - Two Ants Gym - 102823L 题意&#xff1a; 有两个线段A&#xff0c;B&#xff0c;两个线段不会超过一个公共点&#xff0c; 你站在线段B上&#xff0c;整个平面你看不到的区域的面积(如图中S所在区域) 题解&#xff1a; 计算几何&#xff0c;恶心题。调了一个小时还是…

C# 8.0 中开启默认接口实现

当你升级到 C# 8.0 和 .NET Core 3.0 之后&#xff0c;你就可以开始使用默认接口实现的功能了。从现在开始&#xff0c;你可以在接口里面添加一些默认实现的成员&#xff0c;避免在接口中添加成员导致大量对此接口的实现崩溃。要写出并且正常使用接口的默认实现&#xff0c;你需…

P4396 [AHOI2013]作业

P4396 [AHOI2013]作业 题目描述 详见&#xff1a;P4396 [AHOI2013]作业 solution 莫队树状数组的裸题&#xff08;莫队分块&#xff0c;CDQ分治都可以&#xff0c;莫队线段树大概需要卡常&#xff09;。 时间复杂度 Code #include<bits/stdc.h> using namespac…