BZOJ3575 HNOI2014 道路阻塞
3575: [Hnoi2014]道路堵塞
Time Limit: 10 Sec Memory Limit: 128 MB
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
1 2 2
1 3 2
3 4 4
3 2 1
2 4 3
1 5
Sample Output
6
HINT
100%的数据满足2<N<100000,1<M<200000。所用道路长度大于0小于10000。
数据已加强By Vfleaking
你看见我的跳蚤国王了吗?哦它被FFF了?资磁!
这题真是火的冒烟,劲爆无比,谁也想不到正解来自一个很扯淡的证明。
正解:SPFA鬼畜技巧。
因为它已经钦定了最短路,而且要对最短路上每一条边输出一次答案,所以很容易想到正解是枚举BAN哪条边再鬼一鬼。
这里有个十分扯淡的证明:新·最短路一腚是S->之前最短路上某一点p->之前最短路上某一点q->T;
感觉并不知道怎么证明是吧,但如果我说S和p,q和T 可以为同一个点呢?
那么所有的情况都被包含了是的吗?没错是的。您强×把答案放在了一个鬼证明上。
所以按照这个证明的思想,我们枚举删掉最短路上的哪条边,然后把这条边的s加进队列做SPFA。
但是这样不加优化的做法会让你过吗?答案是显然否定的。那么来点更劲的:
先把最短路上的所有边都BAN掉,然后从S到T开始恢复边,并把s丢进队列。
然后每次就可以不清空dis数组了,因为你之前SPFA的结果你都可以调用以前的结果。
然后统计答案就是把走到的钦定最短路上的点的距离加上它到T的距离取个min就好了。这里有一个玄妙的做法就是把答案加上这个点放成结构体扔进堆里,每次弹出到达点在s之前的点因为这是在这条路被BAN的时候SPFA到的,不一定是当前的合法方案,也不会比最优答案更好。所以判完-1后,第一个在s之后的点就不管是不是s更新的点了,却又是一个合法的点,就避免了很多麻烦。
代码还是很好看懂的。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
#include <complex>
#include <stack>
#define LL long long int
#define dob double
using namespace std; const int N = 200010;
struct Node{int from,to,val,next;}E[N];
struct Data{int p,val;bool operator <(const Data &b)const{return val>b.val;}};
int n,m,L,head[N],tot,ban[N],rk[N],In[N],far[N],dis[N],fr[N],s[N];
queue<int>Q;priority_queue<Data>T; int gi()
{
int x=0,res=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')res*=-1;ch=getchar();}
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*res;
} inline void link(int u,int v,int c)
{
E[++tot]=(Node){u,v,c,head[u]};
head[u]=tot;
} inline void SPFA(int st)
{
queue<int>Q;Q.push(st);
while(!Q.empty()){
int x=Q.front();Q.pop();In[x]=0;
for(int e=head[x];e;e=E[e].next){
if(ban[e])continue;int y=E[e].to;
if(far[x]+E[e].val<far[y]){
far[y]=far[x]+E[e].val;
if(fr[y])T.push((Data){fr[y],far[y]+dis[fr[y]]});
else if(!In[y])Q.push(In[y]=y);
}
}
}
} int main()
{
n=gi();m=gi();L=gi();
for(int i=1;i<=m;++i){
int u=gi(),v=gi(),c=gi();
link(u,v,c);
}
s[1]=1;fr[1]=1;
for(int i=1;i<=L;++i){
ban[rk[i]=gi()]=1;
s[i+1]=E[rk[i]].to;
fr[s[i+1]]=i+1;
}
for(int i=L;i;--i)
dis[i]=dis[i+1]+E[rk[i]].val;
memset(far,127/3,sizeof(far));far[1]=0;
SPFA(1);
for(int i=1;i<=L;++i){
while(!T.empty() && T.top().p<=i)T.pop();
if(T.empty())printf("-1\n");
else printf("%d\n",T.top().val);
far[E[rk[i]].to]=far[s[i]]+E[rk[i]].val;
SPFA(s[i+1]);
}
return 0;
}
这还真TMD妙不可言,玄之又玄,精妙绝伦啊(伦boy:嗯?)。
BZOJ3575 HNOI2014 道路阻塞的更多相关文章
- bzoj3575[Hnoi2014]道路堵塞
http://www.lydsy.com/JudgeOnline/problem.php?id=3575 总赶脚第二题总是比第三题难...... 好吧,这题一点思路都没有 听说用民科可以过掉大部分数据 ...
- 洛谷 [HNOI2014]道路堵塞 解题报告
[HNOI2014]道路堵塞 题意 给一个有向图并给出一个这个图的一个\(1\sim n\)最短路,求删去这条最短路上任何一条边后的最短路. 又事SPFA玄学... 有个结论,新的最短路一定是\(1\ ...
- 动态删边SPFA: [HNOI2014]道路堵塞
[HNOI2014]道路堵塞 题目描述 $A$ 国有 $N$座城市,依次标为$1$到$N$.同时,在这$N$座城市间有$M$条单向道路,每条道路的长度是一个正整数.现在,$A$国交通部指定了一条从城市 ...
- 【bzoj3575】 Hnoi2014—道路堵塞
http://www.lydsy.com/JudgeOnline/problem.php?id=3575 (题目链接) 题意 给出一个有向图和一条最短路,问最短路上任意一条边断掉,此时的最短路是多少. ...
- bzoj 3575: [Hnoi2014]道路堵塞
Description A 国有N座城市,依次标为1到N.同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数.现在,A国交通部指定了一条从城市1到城市N的路径, 并且保证这条路径的长度是所 ...
- [HNOI2014]道路堵塞
题目描述 A国有N座城市,依次标为1到N.同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数.现在,A国交通部指定了一条从城市1到城市N的路径,并且保证这条路径的长度是所有从城市1到城市N ...
- luogu P3238 [HNOI2014]道路堵塞
传送门 这什么题啊,乱搞就算了,不知道SPFA已经死了吗 不对那个时候好像还没死 暴力就是删掉边后跑Dijkstra SPFA 然后稍微分析一下,可以发现题目中要求的不经过最短路某条边的路径,一定是先 ...
- BZOJ.3575.[HNOI2014]道路堵塞(最短路 动态SPFA)
题目链接 \(Description\) 给你一张有向图及一条\(1\)到\(n\)的最短路.对这条最短路上的每条边,求删掉这条边后\(1\)到\(n\)的最短路是多少. \(Solution\) 枚 ...
- 【BZOJ】3575: [Hnoi2014]道路堵塞
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3575 大概的做法是,按照顺序枚举每一条要删去的边,(假设当前点为$u$,在最短路径上的下一 ...
随机推荐
- javaSE_05Java中方法(函数)与重载、递归
1.方法的声明和调用 什么是方法?为什么需要方法?代码复用,方便软件升级 什么是方法? 具备特定功能的一段独立的代码段 标准的方法格式:(注意格式的顺序) 修饰符 返回值类型 方法名(参数类型 参数名 ...
- python语言精粹《一》
第一章 静态语言:需要声明类型.变量不能改变类型! 动态语言:(也称脚本语言)主要的应用场景都是很短的应用程序(脚本),比如给静态语言编写的程序进行数据预处理.这样的程序通常也统称胶水代码. pyth ...
- unity3D:游戏分解之角色移动和相机跟随
游戏中,我们经常会有这样的操作,点击场景中某个位置,角色自动移动到那个位置,同时角色一直是朝向那个位置移动的,而且相机也会一直跟着角色移动.有些游戏,鼠标滑动屏幕,相机就会围绕角色旋转. ...
- python基础操作_文件读写操作
#文件读写# r只能读不能写,且文件必须存在,w只能写不能读,a只能写不能读# w+是写读模式,清空原文件内容# r+是读写模式,没有清空原文件内容,# 只要有r,文件必须存在,只要有w,都会清空原文 ...
- 浅谈this那些事
一直以来,对this的讨论都是热门话题.有人说掌握了this就掌握了JavaScript的80%,说法有点夸张,但可见this的重要性.本人至今也是记录了很多关于this的零碎笔记,今天就来个小结. ...
- for循环 重点题
1.冒泡排序 (特别重要): <script type="text/javascript"> var attr=Array(); for(var i=0; i< ...
- grid编辑后时间格式不对问题
在column中应该定义xtype和format格式: xtype: 'datecolumn', format:'Y-m-d' 之后正常
- python 解析docx文档的方法,以及利用Python从docx文档提取插入的文本对象和图片
首先安装docx模块,通过pip install docx或者在docx官方链接上下载安装都可以 下面来看下如何解析docx文档:文档格式如下 有3个部分组成 1 正文:text文档 2 一个表格. ...
- python爬虫从入门到放弃前奏之学习方法
首谈方法 最近在整理爬虫系列的博客,但是当整理几篇之后,发现一个问题,不管学习任何内容,其实方法是最重要的,按照我之前写的博客内容,其实学起来还是很点枯燥不能解决传统学习过程中的几个问题: 这个是普通 ...
- jmeter3.2版本完美实现Load Test报表
今天下载了最新版的apache tomcat jmeter 3.2,需要jdk1.8以上的版本. 用非GUI模式运行压力测试后,出现的报表太完美了. 将jmx脚本放在就jmeter_home下的Scr ...