洛谷 P1119 灾后重建 最短路+Floyd算法
题面
题目链接
题目描述
B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响。但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车。换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄。
给出B地区的村庄数 $ N $ ,村庄编号从 $ 0 $ 到 $ N−1 $ ,和所有 $ M $ 条公路的长度,公路是双向的。并给出第 $ i $ 个村庄重建完成的时间 $ t_i $ ,你可以认为是同时开始重建并在第 $ t_i $ 天重建完成,并且在当天即可通车。若 $ t_i $ 为 $ 0 $ 则说明地震未对此地区造成损坏,一开始就可以通车。之后有 $ Q $ 个询问 $ (x,y,t) $ ,对于每个询问你要回答在第 $ t $ 天,从村庄 $ x $ 到村庄 $ y $ 的最短路径长度为多少。如果无法找到从 $ x $ 村庄到 $ y $ 村庄的路径,经过若干个已重建完成的村庄,或者村庄 $ x $ 或村庄 $ y $ 在第t天仍未重建完成 ,则需要返回 $ -1 $ 。
输入输出格式
输入格式
第一行包含两个正整数 $ N,M $ ,表示了村庄的数目与公路的数量。
第二行包含 N 个非负整数 $ t_0, t_1,…, t_{N-1} $ ,表示了每个村庄重建完成的时间,数据保证了 $ t_0 \leq t_1 \leq ... \leq t_{N-1} $
接下来 $ M $ 行,每行 $ 3 $ 个非负整数 $ i,j,w $ , $ w $ 为不超过 $ 10000 $ 的正整数,表示了有一条连接村庄 $ i $ 与村庄 $ j $ 的道路,长度为 $ w $ ,保证 $ i≠j $,且对于任意一对村庄只会存在一条道路。
接下来一行也就是 $ M+3 $ 行包含一个正整数 $ Q $ ,表示 $ Q $ 个询问。
接下来 $ Q $ 行,每行 $ 3 $ 个非负整数 $ x,y,t $ ,询问在第 $ t $ 天,从村庄 $ x $ 到村庄 $ y $ 的最短路径长度为多少,数据保证了 $ t $ 是不下降的。
输出格式
共 $ Q $ 行,对每一个询问 $ (x,y,t) $ 输出对应的答案,即在第 $ t $ 天,从村庄 $ x $ 到村庄 $ y $ 的最短路径长度为多少。如果在第 $ t $ 天无法找到从 $ x $ 村庄到 $ y $ 村庄的路径,经过若干个已重建完成的村庄,或者村庄 $ x $ 或村庄 $ y $ 在第 $ t $ 天仍未修复完成,则输出 $ -1 $ 。
输入输出样例
输入样例
4 5
1 2 3 4
0 2 1
2 3 1
3 1 2
2 1 4
0 3 5
4
2 0 2
0 1 2
0 1 3
0 1 4
输出样例
-1
-1
5
4
说明
【数据范围】
对于30%的数据,有 $ N \leq 50 $;
对于30%的数据,有 $ t_i=0 $ ,其中有 20% 的数据有 $ t_i=0 $ 且 $ N>50 $ ;
对于50%的数据,有 $ Q \leq 100 $ ;
对于100%的数据,有 $ N≤200 $ ,$ M \leq N \times (N-1) / 2 $ , $ Q \leq 50000 $ ,所有输入数据涉及整数均不超过 100000 。
【时空限制】
1000ms,128M
思路
首先看到要多次询问两点间的最短路,可以考虑用Floyd算法。可是两点间的距离是随着时间而变化的,怎么办呢?
显然我们可以这样做:当每次询问时,我们将此时已经修建好的村庄之间跑一遍Floyd,其他村庄不管。但是这样做肯定会TLE。
想想怎么优化。注意到询问时 $ t_i $ 是递增的,村庄修建好的顺序也是递增的,那么我们可以记录一个当前修建好的村庄的最大编号。每次询问时,看是否有新的村庄修好了,如果有,那么把他加进来作为中转点跑一次最短路
AC代码
#include<bits/stdc++.h>
const int maxn=210;
using namespace std;
int n,m,T[maxn];
int Q,np;
int dis[maxn][maxn];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&T[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) if(i!=j)
dis[i][j]=INT_MAX/2;
for(int i=1;i<=m;i++)
{
int u,v,w;scanf("%d%d%d",&u,&v,&w);
u++;v++;
dis[u][v]=min(dis[u][v],w);
dis[v][u]=min(dis[v][u],w);
}
scanf("%d",&Q);
np=1;
for(int i=1;i<=Q;i++)
{
int u,v,t;scanf("%d%d%d",&u,&v,&t);
u++,v++;
for(np;T[np]<=t && np<=n;np++)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dis[i][j]=min(dis[i][j],dis[i][np]+dis[np][j]);
}
if(T[u]<=t && T[v]<=t && dis[u][v]!=INT_MAX/2) printf("%d\n",dis[u][v]);
else printf("-1\n");
}
return 0;
}
总结
优化的这一步可以说题目也提示了很多。如果题中没有给递增条件,也许我就不会做了。
洛谷 P1119 灾后重建 最短路+Floyd算法的更多相关文章
- 洛谷——P1119 灾后重建
P1119 灾后重建 题目背景 B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重 ...
- 洛谷 P1119 灾后重建——dijstra
先上一波题目 https://www.luogu.org/problem/P1119 这道题我们可以将询问按时间排序 然后随着询问将相应已经重建成功的点进行操作 每次更新一个点就以他为起点跑一遍dij ...
- 洛谷P1119 灾后重建[Floyd]
题目背景 B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路才能 ...
- 洛谷P1119 灾后重建 Floyd + 离线
https://www.luogu.org/problemnew/show/P1119 真是有故事的一题呢 半年前在宁夏做过一道类似的题,当时因为我的愚昧痛失了金牌. 要是现在去肯定稳稳的过,真是生不 ...
- 洛谷P1119灾后重建——Floyd
题目:https://www.luogu.org/problemnew/show/P1119 N很小,考虑用Floyd: 因为t已经排好序,所以逐个加点,Floyd更新即可: 这也给我们一个启发,如果 ...
- 洛谷 P1119 灾后重建(Floyd)
嗯... 题目链接:https://www.luogu.org/problem/P1119 这道题是一个Floyd的很好的题目,在Floyd的基础上加一点优化: 中转点k在这里不能暴力枚举,否则会超时 ...
- 洛谷 [P1119] 灾后重建
我们发现每次询问都是对于任意两点的,所以这是一道多源最短路径的题,多源最短路径,我们首先想到floyd,因为询问的时间是不降的,所以对于每次询问,我们将还没有进行松弛操作的的点k操作. #includ ...
- 洛谷P1119灾后重建
题目 做一个替我们首先要明确一下数据范围,n<=200,说明n^3的算法是可以过得,而且这个题很明显是一个图论题, 所以我们很容易想到这个题可以用folyd, 但是我在做这个题的时候因为没有深刻 ...
- 洛谷P1119 灾后重建
传送门 题目大意:点被破坏,t[i]为第i个点修好的时间,且t[1]<t[2]<t[3].. 若干询问,按时间排序,询问第t时刻,u,v的最短路径长度. 题解:floyed 根据时间加入点 ...
随机推荐
- python 日记 day4。
1.为何数据要分类 数据是用来表示状态的,不同的状态应该用不同类型的数据来表示. 2.数据类型 数字 字符串 列表 元组 字典 集合 列表:列表相比于字符串,不仅可以储存不同的数据类型,而且可以储存大 ...
- 【vue】vue-znly
老规矩,放下博主的项目地址:https://github.com/wohaiwo/vue-znly 我一直在想给那些开源者取什么名字比较好,怎样才对得起他们开源项目的精神,后来想想,还是叫博主吧.有的 ...
- 更改电脑用户名(可更改C:\Users\用户名)
参考:http://blog.csdn.net/zhang_jinhe/article/details/40624847 假设我们需要将帐户A改名为B. 首先我们需要用另一个管理员帐户C登陆系统. 1 ...
- div 无缝滚动
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org ...
- localStorage对象简单应用 - - 访问次数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 零开始Android逆向教程(一)——初探Android逆向
这段时间因为某些业务驱动,开始研究一些逆向相关的东西,浏览了下其所包含的大致内容,发现真是一个新大陆,跟之前耳听目染过的一些门面介绍完全不是一个层级的,真正的印证了下手难这一说法. 谨此以本文开始 ...
- 读书笔记--Head First 设计模式 目录
1.设计模式入门 2.观察者模式 3.装饰者模式 4.工厂模式 5.单件模式 6.命令模式 7.适配器模式与外观模式 8.模板方法模式 9.迭代器与组合模式 10.状态模式 11.代理模式 12.复合 ...
- mybatis深入理解(六)-----MyBatis的二级缓存的设计原理
MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分析MyBatis的二级缓存的设计原理. 1.MyBatis的缓存机制整体设计以及 ...
- 学习Python笔记---操作列表
1.for循环: 编写for循环时,对于用语存储列表中每个值的临时变量,可指定任何名称. 在for循环中,想包含多少行代码都可以,每个缩进的代码行都是循环的一部分,且将针对列表中的每个值都执行一次. ...
- 类的加载classload和类对象的生成
在Java中最重要的可以说就是类的加载了.不论我们编写的功能多么复杂,或是多么简单,永远逃离不开的,就是将这个类从class文件加载到JVM中来. 类的加载过程 首先我们要了解一下类的加载过程,包括: ...