[HNOI 2014]道路堵塞
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$次拓展慢的吓人<代码中沿用,简洁一些(其实我懒,不想改)>。
1 #include<set> 2 #include<map> 3 #include<queue> 4 #include<stack> 5 #include<cmath> 6 #include<ctime> 7 #include<string> 8 #include<cstdio> 9 #include<vector> 10 #include<cstring> 11 #include<cstdlib> 12 #include<iostream> 13 #include<algorithm> 14 #define LL long long 15 #define RE register 16 #define IL inline 17 using namespace std; 18 const int N=100000; 19 const int M=200000; 20 21 IL int Read(); 22 23 int n,m,l,sp[N+5]; 24 int last[N+5],id[N+5]; 25 struct Link 26 { 27 int from,to,cost; 28 }lin[M+5]; 29 struct tt 30 { 31 int to,next,cost,id; 32 }edge[M+5]; 33 int path[N+5],top; 34 IL void Add(int u,int v,int c,int id); 35 36 struct node 37 { 38 int u,dis; 39 bool operator < (const node &b) 40 const{ 41 return dis>b.dis; 42 } 43 }; 44 priority_queue<node>Q; 45 46 int dis[N+5]; 47 bool vis[N+5]; 48 IL void SPFA(int donot); 49 50 int main() 51 { 52 n=Read();m=Read();l=Read(); 53 for (RE int i=1;i<=m;i++) 54 { 55 lin[i].from=Read();lin[i].to=Read();lin[i].cost=Read(); 56 Add(lin[i].from,lin[i].to,lin[i].cost,i); 57 } 58 id[1]=1; 59 for (RE int i=1;i<=l;i++) sp[i]=Read(),id[lin[sp[i]].to]=id[lin[sp[i]].from]+1; 60 for (RE int i=l;i;i--) last[lin[sp[i]].from]=last[lin[sp[i]].to]+lin[sp[i]].cost; 61 memset(dis,127/3,sizeof(dis));dis[1]=0; 62 for (RE int i=1;i<=l;i++) 63 { 64 if (i>1) dis[lin[sp[i-1]].to]=dis[lin[sp[i-1]].from]+lin[sp[i-1]].cost; 65 SPFA(sp[i]); 66 while (!Q.empty()&&id[lin[sp[i]].from]>=id[Q.top().u]) Q.pop(); 67 printf("%d\n",Q.empty() ? -1:Q.top().dis); 68 } 69 return 0; 70 } 71 72 IL void SPFA(int donot) 73 { 74 queue<int>q; 75 while (!q.empty()) q.pop(); 76 q.push(lin[donot].from); 77 memset(vis,0,sizeof(vis)); 78 while (!q.empty()) 79 { 80 for (RE int i=path[q.front()];i;i=edge[i].next) if (edge[i].id!=donot) 81 { 82 if (dis[edge[i].to]>dis[q.front()]+edge[i].cost) 83 { 84 dis[edge[i].to]=dis[q.front()]+edge[i].cost; 85 if (id[edge[i].to]) Q.push((node){edge[i].to,dis[edge[i].to]+last[edge[i].to]}); 86 else if (!vis[edge[i].to]) 87 { 88 vis[edge[i].to]=1; 89 q.push(edge[i].to); 90 } 91 } 92 } 93 vis[q.front()]=0; 94 q.pop(); 95 } 96 } 97 IL void Add(int u,int v,int c,int id) 98 { 99 edge[++top].to=v; 100 edge[top].cost=c; 101 edge[top].id=id; 102 edge[top].next=path[u]; 103 path[u]=top; 104 } 105 IL int Read() 106 { 107 char c=getchar(); 108 int sum=0; 109 while (c<'0'||c>'9') c=getchar(); 110 while (c>='0'&&c<='9') sum=sum*10+c-'0',c=getchar(); 111 return sum; 112 }
转载于:https://www.cnblogs.com/NaVi-Awson/p/7246201.html
[HNOI 2014]道路堵塞相关推荐
- [HNOI 2014] 米特运输
[HNOI 2014] 米特运输 题目描述 题目 题目描述 输入格式 输出格式 样例输入 样例输出 提示 解题过程 思路 代码 感想 题目描述 一道树形dp 题目 题目描述 米特是D星球上一种非常神秘 ...
- luogu P4438 [HNOI/AHOI2018]道路
题目传送门:https://www.luogu.org/problemnew/show/P4438 题意: 有n-1个点为城市,n-1个点为农村,每个城市连出两种道路,一边为公路,一边为铁路.现在每一 ...
- 洛谷4438 [HNOI/AHOI2018]道路
标签:树形DP 题目 题目传送门 题目描述 W 国的交通呈一棵树的形状.W 国一共有n−1n - 1n−1个城市和nnn个乡村,其中城市从111到n−1n - 1n−1 编号,乡村从111到nnn编号 ...
- Luogu 4438 [HNOI/AHOI2018]道路
$dp$. 这道题最关键的是这句话: 跳出思维局限大胆设状态,设$f_{x, i, j}$表示从$x$到根要经过$i$条公路,$j$条铁路的代价,那么对于一个叶子结点,有$f_{x, i, j} = ...
- [HNOI 2014]画框
Description 题库链接 \(T\) 组询问,每组询问给你个 \(2\times N\) 的带权二分图,两个权值 \(a,b\) ,让你做匹配使得 \[\sum a\times \sum b\ ...
- 【bzoj3575】 Hnoi2014—道路堵塞
http://www.lydsy.com/JudgeOnline/problem.php?id=3575 (题目链接) 题意 给出一个有向图和一条最短路,问最短路上任意一条边断掉,此时的最短路是多少. ...
- 【BZOJ】3575: [Hnoi2014]道路堵塞
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3575 大概的做法是,按照顺序枚举每一条要删去的边,(假设当前点为$u$,在最短路径上的下一 ...
- BZOJ5290 洛谷4438:[HNOI/AHOI2018]道路——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5290 https://www.luogu.org/problemnew/show/P4438 的确 ...
- BZOJ.3575.[HNOI2014]道路堵塞(最短路 动态SPFA)
题目链接 \(Description\) 给你一张有向图及一条\(1\)到\(n\)的最短路.对这条最短路上的每条边,求删掉这条边后\(1\)到\(n\)的最短路是多少. \(Solution\) 枚 ...
最新文章
- Raid技术在Linux下的使用
- wxWidgets:窗口大小概述
- 第一章计算机网络概述答案,第一章 计算机网络概述[3]
- java小项目实例,成功入职阿里
- 解码错误。‘gb2312‘ codec can‘t decode byte 0xf3 in position 307307: illegal multibyte sequence
- mongodb mysql资源占用_如何限制mongodb启动时占用过多内存
- 方案改进:直接通过User Control生成HTML
- python tkinter背景图片_如何在tkinter中有背景图像和按钮?
- Redis之Redis事务
- pycharm下自建python包引入失败解决方案
- android 比较全的android 源码合集 + 企业级应用分享,从业的积累(毕业设计集合版)
- 《嵌入式-STM32开发指南》第三部分 外设篇 - 第5章 光敏传感器
- matlab南方平差易,测量平差实习心得多篇
- scala 2.13 并行集合par 的引用
- 垃圾短信分类java_有了这个神器,快速告别垃圾短信邮件
- OpenAI又放大招:连接文本与图像的CLIP,在ImageNet上效果媲美ResNet50
- Taprint: Secure Text Input for Commodity Smart Wristbands
- 如何全网智能识别文章页,识别正文和标题
- 平面设计需要学习什么,平面设计是什么;夏雨老师
- OC中的非正式协议与正式协议的区别
热门文章
- python图形界面开发库_Python图形界面开发—wxPython库的布局管理及页面切换
- 算法——动态规划算法
- 如何使用小程序自定义组件功能
- Linq 使用skip和take分页
- 电脑静音工作,又听不到12306的来票音乐,纠结啊 !但春节前工作多任务重,不能安心工作,就动手做个“无声购票弹窗”工具吧!...
- 修改Android中strings.xml文件, 动态改变数据
- centos---centos配置svn
- Python接口自动化之yaml配置文件
- 反向传播和梯度下降的区分
- 美SEC委员:不要轻易创建NFT,它可能被归类为证券