Description

A国有N座城市,依次标为1到N。同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数。现在,A国 交通部指定了一条从城市1到城市N的路径,并且保证这条路径的长度是所有从城市1到城市N的路径中最短的。不幸的是,因为从城市1到城市N旅行的人越来越 多,这条由交通部指定的路径经常发生堵塞。现在A国想知道,这条路径中的任意一条道路无法通行时,由城市1到N的最短路径长度是多少。

Input

输入文件第一行是三个用空格分开的正整数N、M和L,分别表示城市数目、单向道路数目和交通部指定 的最短路径包含多少条道路。按下来M行,每行三个用空格分开的整数a、b和c,表示存在一条由城市a到城市b的长度为c的单向道路。这M行的行号也是对应 道路的编号,即其中第1行对应的道路编号为1,第2行对应的道路编号为2,...,第M行对应的道路编号为M。最后一行为L个用空格分开的整数 sp(1)...,,sp(L),依次表示从城市1到城市N的由交通部指定的最短路径上的道路的编号。

Output

输出文件包含L行,每行为一个整数,第i行(i=1,2...,,L)的整数表示删去编号为sp(i)的道路后从城市1到城市N的最短路径长度。如果去掉后没有从城市1到城市N的路径,则输出一1。

Sample Input

4 5 2
1 2 2
1 3 2
3 4 4
3 2 1
2 4 3
1 5

Sample Output

6
6

Hint

100%的数据满足2<N<100000,1<M<200000。所用道路长度大于0小于10000。

题目大意

给出一个N个节点,M条边的有向图。给出一条1到N的最短路,问最短路上任意一条边断掉,此时的最短路是多少。

题解

考虑不可能每次删掉当前边之后再跑一遍最短路,那必须想办法优化删边和求得最短路过程。

我们将最短路上的点从小到大标号。

考虑删边之后,当前的从$1$到$N$的最短路只能是从$1$出发,在最短路径上走一段,再走一段非最短路,最后回到最短路径上。那么如果强制不走当前边,在跑最短路的过程中,只要发现走到了一个最短路径上的点上时(这个点肯定是最短路上标号更大的点),既然在最短路上,就不必要继续松弛了,显然$SPFA$求出的$dis$值+该点到终点的距离$last$就是一个可行的解,更新$ans$。

其实上述过程得到的解还是没有充分利用的。我们会发现,以后的$SPFA$搜到解会和当前这次$SPFA$得到的解重复。这些重复的解的共同特点就是终止的节点的标号都大于这两个的标号。(想象一下,既然第一次搜到了一个标号很大的解,显然它是没有在这个点之前走上最短路的,就是它同时也绕过了后来的一条强制不走的边),所以这个解是可以继续用的。

用堆保存一下走到哪个在最短路上的点导致的更新$ans$的话,就可以在以后反复调用,保证全局最优了。注意每次跑$SPFA$无需清空$dis$,因为最短路从左往右做的时候,$dis$显然递减(想一想最短路的松弛操作),但是到达最短路上的点的标记必须清空。

玄学的时间复杂度...也能过...人生处处是惊喜...难道不是吗?

$SPFA$的时候不要用$STL$中的$queue$,$n$次拓展慢的吓人<代码中沿用,简洁一些(其实我懒,不想改)>。

 #include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<string>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define LL long long
#define RE register
#define IL inline
using namespace std;
const int N=;
const int M=; IL int Read(); int n,m,l,sp[N+];
int last[N+],id[N+];
struct Link
{
int from,to,cost;
}lin[M+];
struct tt
{
int to,next,cost,id;
}edge[M+];
int path[N+],top;
IL void Add(int u,int v,int c,int id); struct node
{
int u,dis;
bool operator < (const node &b)
const{
return dis>b.dis;
}
};
priority_queue<node>Q; int dis[N+];
bool vis[N+];
IL void SPFA(int donot); int main()
{
n=Read();m=Read();l=Read();
for (RE int i=;i<=m;i++)
{
lin[i].from=Read();lin[i].to=Read();lin[i].cost=Read();
Add(lin[i].from,lin[i].to,lin[i].cost,i);
}
id[]=;
for (RE int i=;i<=l;i++) sp[i]=Read(),id[lin[sp[i]].to]=id[lin[sp[i]].from]+;
for (RE int i=l;i;i--) last[lin[sp[i]].from]=last[lin[sp[i]].to]+lin[sp[i]].cost;
memset(dis,/,sizeof(dis));dis[]=;
for (RE int i=;i<=l;i++)
{
if (i>) dis[lin[sp[i-]].to]=dis[lin[sp[i-]].from]+lin[sp[i-]].cost;
SPFA(sp[i]);
while (!Q.empty()&&id[lin[sp[i]].from]>=id[Q.top().u]) Q.pop();
printf("%d\n",Q.empty() ? -:Q.top().dis);
}
return ;
} IL void SPFA(int donot)
{
queue<int>q;
while (!q.empty()) q.pop();
q.push(lin[donot].from);
memset(vis,,sizeof(vis));
while (!q.empty())
{
for (RE int i=path[q.front()];i;i=edge[i].next) if (edge[i].id!=donot)
{
if (dis[edge[i].to]>dis[q.front()]+edge[i].cost)
{
dis[edge[i].to]=dis[q.front()]+edge[i].cost;
if (id[edge[i].to]) Q.push((node){edge[i].to,dis[edge[i].to]+last[edge[i].to]});
else if (!vis[edge[i].to])
{
vis[edge[i].to]=;
q.push(edge[i].to);
}
}
}
vis[q.front()]=;
q.pop();
}
}
IL void Add(int u,int v,int c,int id)
{
edge[++top].to=v;
edge[top].cost=c;
edge[top].id=id;
edge[top].next=path[u];
path[u]=top;
}
IL int Read()
{
char c=getchar();
int sum=;
while (c<''||c>'') c=getchar();
while (c>=''&&c<='') sum=sum*+c-'',c=getchar();
return sum;
}

[HNOI 2014]道路堵塞的更多相关文章

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

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

  2. HNOI 2014

    D1T1:画框 frame 题意:给你两个n阶正整数方阵,请你求最大的\( \sum_{i = 1}^{n} A_{i, p_i}\times \sum_{i = 1}^{n} B_{i, p_i}  ...

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

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

  4. HNOI 2014 米特运输(图论)

    HNOI 2014 米特运输 题目大意 给一棵树,每个点有自己的权值,要求更改一些点的权值,使得整棵树满足两个条件: 同一个父亲的所有子节点权值相同 父节点的取值为所有子节点的和 答案输出最少要更改的 ...

  5. BZOJ 3575 道路堵塞

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

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

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

  7. [HNOI2014]道路堵塞

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

  8. 数据结构(虚树,动态规划):HNOI 2014 世界树

    Hnoi2014 世界树 Description 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平 ...

  9. [HNOI/AHOI2018]道路

    Description: W 国的交通呈一棵树的形状.W 国一共有\(n - 1\)个城市和\(n\)个乡村,其中城市从\(1\)到\(n - 1\) 编号,乡村从\(1\)到\(n\)编号,且\(1 ...

随机推荐

  1. Java虚拟机之性能监控

    一.jstat:虚拟机统计信息监控工具监视虚拟机各种运行状态 图中,S0.S1(Survivor0.Survivor1)代表两个Survivor区,其中一个值为57.60%.另一个为0.E(Eden) ...

  2. 网络1711班 C语言第四次作业批改总结

    网络1711班 C语言第四次作业批改总结 助教有话说(写在前面) 近来,有同学跟老师和助教们反映:博客作业太多太麻烦,而且对编程能力提高似乎没什么帮助?在这里我要谈一谈我的感想. 博客作业的意义? 首 ...

  3. pjax实例demo(c#,iis)

    pjax 百度都是api 也没找到demo 自己写了一个 C#写的 需要iis架设 测试ie10 和 火狐 成功 ie10不要用兼容模式 不然不好使 iis 可以直接架设webDemo1文件夹(源码) ...

  4. splinter web测试框架

    1.安装谷歌浏览器驱动(windows把驱动解压放在Python.exe同级目录即可) http://chromedriver.storage.googleapis.com/index.html 注意 ...

  5. NetFPGA-1G-CML Demo --- reference_router_nf1_cml

    环境 deepin 15.4 vivado 15.2 ise 14.6 前期准备 Github Wiki链接:https://github.com/NetFPGA/NetFPGA-public/wik ...

  6. Java中三种比较常见的数组排序

    我们学习数组比较常用的数组排序算法不是为了在工作中使用(这三个算法性能不高),而是为了练习for循环和数组.因为在工作中Java API提供了现成的优化的排序方法,效率很高,以后工作中直接使用即可 . ...

  7. java8-Stream之数值流

    在Stream里元素都是对象,那么,当我们操作一个数字流的时候就不得不考虑一个问题,拆箱和装箱.虽然自动拆箱不需要我们处理,但依旧有隐含的成本在里面.Java8引入了3个原始类型特化流接口来解决这个问 ...

  8. [知识梳理]课本1&2.1-2.5

    面向对象的语言 出发点:更直接地描述客观世界中存在的事物(对象)以及它们之间的关系. 特点: 是高级语言. 将客观事物看作具有属性和行为的对象. 通过抽象找出同一类对象的共同属性和行为,形成类. 通过 ...

  9. nyoj VF

    VF 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述 Vasya is the beginning mathematician. He decided to make ...

  10. LR之error(一)

    1 录制时频繁卡死的解决方案 添加数据保护 路径:计算机--高级系统设置(环境变量设置的上级窗口)--高级--设置--数据执行保护 更改LR录制设置,将run-time setting的brower改 ...