题目链接

\(Description\)

给你一张有向图及一条\(1\)到\(n\)的最短路。对这条最短路上的每条边,求删掉这条边后\(1\)到\(n\)的最短路是多少。

\(Solution\)

枚举删每条边然后求最短路显然不行。考虑怎么保留之前求最短路的一些信息。

考虑删掉一条边后的最短路,\(1\)沿最短路到了某个点\(x\),然后如果\(x\)到了最短路上的某点\(y\),之后一定是沿\(y\)到\(n\)的最短路走到\(n\)。

\(n\)也是最短路上的点,即\(x\)一定会到达某个\(y\)并沿最短路到达\(n\)。这时就可以在\(y\)处直接更新\(Ans\)。

我们发现在\(y\)处的值可以更新所有\(y\)之前最短路的边的\(Ans\)。

我们用堆把这个值及\(y\)前面那条最短路的边的标号\(id\)存下来。如果当前删的边\(i\)大于等于堆顶的\(id\),就可以直接用堆顶的答案了。否则直接\(pop\)掉堆顶。

所以我们把所有最短路边删掉,每求完一条边\((u,v)\)的值时更新\(dis[v]\),然后把\(v\)再加入队列SPFA就行了。

每次SPFA不需要清空\(dis\),\(dis\)是递减的。

当然本题复杂度玄学。

//18720kb	3244ms
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 200000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e5+5,M=2e5+5; int Enum,H[N],nxt[M],fr[M],to[M],len[M],dis[N],dt[N],A[N],pre[N];
bool ban[M];
char IN[MAXIN],*SS=IN,*TT=IN;
struct Node
{
int pos,val;
bool operator <(const Node &x)const
{
return val>x.val;
}
};
std::priority_queue<Node> hp; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AE(int w,int v,int u)
{
to[++Enum]=v, fr[Enum]=u, nxt[Enum]=H[u], H[u]=Enum, len[Enum]=w;
}
void SPFA(int s)
{
static bool inq[N];
static std::queue<int> q;
q.push(s);
while(!q.empty())
{
int x=q.front(); q.pop();
inq[x]=0;
for(int i=H[x],v; i; i=nxt[i])
if(!ban[i]&&dis[v=to[i]]>dis[x]+len[i])
{
dis[v]=dis[x]+len[i];
if(pre[v]) hp.push((Node){pre[v],dis[v]+dt[pre[v]]});
else if(!inq[v]) inq[v]=1, q.push(v);
}
}
} int main()
{
int n=read(),m=read(),l=read();
for(int i=1; i<=m; ++i) AE(read(),read(),read());
for(int i=1,id; i<=l; ++i)
{
A[i]=id=read();
ban[id]=1, pre[to[id]]=i;
}
for(int i=l-1; i; --i) dt[i]=dt[i+1]+len[A[i+1]]; memset(dis,0x3f,sizeof dis);
dis[1]=0, SPFA(1);
for(int i=1,id; i<=l; ++i)
{
while(!hp.empty()&&hp.top().pos<i) hp.pop();
if(hp.empty()) puts("-1");
else printf("%d\n",hp.top().val);
id=A[i], dis[to[id]]=dis[fr[id]]+len[id];
SPFA(to[id]);
} return 0;
}

BZOJ.3575.[HNOI2014]道路堵塞(最短路 动态SPFA)的更多相关文章

  1. bzoj 3575: [Hnoi2014]道路堵塞

    Description A 国有N座城市,依次标为1到N.同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数.现在,A国交通部指定了一条从城市1到城市N的路径, 并且保证这条路径的长度是所 ...

  2. 【BZOJ】3575: [Hnoi2014]道路堵塞

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3575 大概的做法是,按照顺序枚举每一条要删去的边,(假设当前点为$u$,在最短路径上的下一 ...

  3. [HNOI2014] 道路堵塞 - 最短路,线段树

    对不起对不起,辣鸡蒟蒻又来用核弹打蚊子了 完全ignore了题目给出的最短路,手工搞出一个最短路,发现对答案没什么影响 所以干脆转化为经典问题:每次询问删掉一条边后的最短路 如果删掉的是非最短路边,那 ...

  4. 动态删边SPFA: [HNOI2014]道路堵塞

    [HNOI2014]道路堵塞 题目描述 $A$ 国有 $N$座城市,依次标为$1$到$N$.同时,在这$N$座城市间有$M$条单向道路,每条道路的长度是一个正整数.现在,$A$国交通部指定了一条从城市 ...

  5. 洛谷 [HNOI2014]道路堵塞 解题报告

    [HNOI2014]道路堵塞 题意 给一个有向图并给出一个这个图的一个\(1\sim n\)最短路,求删去这条最短路上任何一条边后的最短路. 又事SPFA玄学... 有个结论,新的最短路一定是\(1\ ...

  6. bzoj3575[Hnoi2014]道路堵塞

    http://www.lydsy.com/JudgeOnline/problem.php?id=3575 总赶脚第二题总是比第三题难...... 好吧,这题一点思路都没有 听说用民科可以过掉大部分数据 ...

  7. [HNOI2014]道路堵塞

    题目描述 A国有N座城市,依次标为1到N.同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数.现在,A国交通部指定了一条从城市1到城市N的路径,并且保证这条路径的长度是所有从城市1到城市N ...

  8. 【bzoj3575】 Hnoi2014—道路堵塞

    http://www.lydsy.com/JudgeOnline/problem.php?id=3575 (题目链接) 题意 给出一个有向图和一条最短路,问最短路上任意一条边断掉,此时的最短路是多少. ...

  9. luogu P3238 [HNOI2014]道路堵塞

    传送门 这什么题啊,乱搞就算了,不知道SPFA已经死了吗 不对那个时候好像还没死 暴力就是删掉边后跑Dijkstra SPFA 然后稍微分析一下,可以发现题目中要求的不经过最短路某条边的路径,一定是先 ...

随机推荐

  1. mysql系列六、mysql创建用户、授权、备份及恢复命令

    一.创建用户和授权 下面的操作中,其中someusername为用户名,somepassword为密码,somedbname为数据库名 1.创建用户 create user 'someusername ...

  2. Linux版本Membase无法写入default bucket的问题分析

    最近项目中使用的membase发现出了点问题,生产环境中读写各种数据都正常,可是新搭建的开发环境下,只有default bucket写不进去数据,调用store总是返回FALSE,配置文件也是一模一样 ...

  3. Linux中断处理(一)

    最近在研究异步消息处理, 突然想起linux内核的中断处理, 里面由始至终都贯穿着"重要的事马上做, 不重要的事推后做"的异步处理思想. 于是整理一下~~第一阶段--获取中断号每个 ...

  4. Numpy详解

    NumPy 简介 Python并没有提供数组功能.虽然列表可以完成基本的数组功能,但它不是真正的数组,而且在数据量比较大时,使用列表的速度会很慢.为此,Numpy提供了真正的数组功能,以及对数据进行快 ...

  5. Java 清理和垃圾回收

    java.lang.ref.cleaner包 finalize()//该方法已过时,有风险,慎用 1.对象不可能被垃圾回收 2.垃圾回收并不等于"析构" 只有当垃圾回收发生时fin ...

  6. 关系操作符 < > = == <= >= !=

    基本类型可以用所有的操作符 对象要用equal eqauls() //用法 System.out.println(v1.equals(v2)); JAVA学习(二) STRING使用EQUALS方法和 ...

  7. poj1179 环形+区间dp

    因为要用到模,所以左起点设置为0比较好 #include<iostream> #include<cstdio> #include<cstring> #define ...

  8. 有关列分组,定义css样式无效的问题

    声明: web前端学习笔记,欢迎大神指点.联系QQ:1522025433. 有时候我们要单独对表格的某列定义单独的样式,就会很自然的想到 表格的 在<table>标签内使用的 <co ...

  9. 《剑指offer》-斐波那契数列

    大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项. n<=39 这么直接的问fibonacci,显然是迭代计算.递归的问题在于重复计算,而迭代则避免了这一点:递归是自 ...

  10. poj 1631 最多能有多少条不交叉的线 最大非降子序列 (LIS)

    左边的数字是1 2 3 4 5.... 右边的数字 第一个输入的和1连 第2个输入的和2连 右边再按从小到大排序 要求连线不能交叉 问最多能有多少条不交叉的线 假如右边有5个1 那么答案会是5 所以是 ...