题解:洛谷P1119 灾后重建

题目传送门

前言:没有掌握floyed求最短路的精髓是每次增加选一个中转点,导致写了2h才勉强卡过

法1:最暴力的想法就是开个三维数组把前i个点的dis状态全部存下来,跑N次floyed,当然由于每次点数时递增的,所以实际复杂度远远小于O(N^4),算了下大概200个点跑了4e8多一点点,卡卡常开O2还是能过(不吸氧只有40,逃)

#include<bits/stdc++.h>
#define ri register int
#define F(i,l,r) for(ri i=l;i<=r;++i)
using namespace std;
char buf[1<<19],*p1=buf,*p2=buf;
inline int gc(){ return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,1<<19,stdin),p1==p2)?EOF:*p1++; }
inline int rd(){
ri x=0; char ch=gc();
while(!isdigit(ch)) ch=gc();
while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=gc();
return x;
}
const int inf=0x3f3f3f3f;
int n,m,q,t[205],g[100003],dis[202][202][202];//g[i]:t=i时的点数
inline void ini(){
memset(dis,0x3f,sizeof(dis)); F(i,0,n-1) F(j,0,n-1) dis[j][j][i]=0;
F(i,1,n-2) F(j,t[i],t[i+1]-1) g[j]=i;
F(i,0,t[0]-1) g[i]=-1; F(i,t[n-1],100000) g[i]=n-1;
}
int main(){
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
int u,v,ti; n=rd(),m=rd(); F(i,0,n-1) t[i]=rd();
ini();
F(i,1,m) u=rd(),v=rd(),ti=rd(),dis[u][v][0]=ti,dis[v][u][0]=ti;
F(p,0,n-1){
if(p>0) F(i,0,n-1) F(j,0,n-1) dis[i][j][p]=dis[i][j][p-1];
F(k,0,p) F(i,0,p) F(j,0,p) dis[i][j][p]=min(dis[i][k][p]+dis[k][j][p],dis[i][j][p]);
}
q=rd(); while(q--){
u=rd(),v=rd(),ti=rd();
if(g[ti]<0 || u>g[ti] || v>g[ti] || dis[u][v][g[ti]]==inf) puts("-1");
else printf("%d\n",dis[u][v][g[ti]]);
}
return 0;
}

法2:

1.留意到法1中的做法其实很浪费:第p轮更新却要把前p-1轮重复的再算一遍,能不能优化呢?

2.发现每次随时间新加进来点k后,可能被改变的dis其实只有过了k点的dis,我们惊讶地发现这不就是以k为中转站去更新dis吗?前k-1个点作为中转站的dis是不受影响的。所以每次询问都把当前 t 新修好的点加入最短路更新 dis 即可,不用每次重新算。

3.再结合floyed的本质:外层k的累加,代表着允许前1个点作为中转站,前2个点,前3个点...前k个点来更新dis状态, 用一句话概括就是:从i号顶点到j号顶点只经过前k号点的最短路程。

4.题上询问的t又是递增的,所以在线加点没有问题,这样dis只用开两维,时间复杂度O(N^3)

...
inline void upd(int k){
F(i,0,n-1) F(j,0,n-1) dis[i][j]=min(dis[i][k]+dis[k][j],dis[i][j]);
}
int main(){
...
int nw=0;
q=rd(); while(q--){
u=rd(),v=rd(),ti=rd();
while(t[nw]<=ti && nw<n) upd(nw++);
if(t[u]>ti || t[v]>ti || dis[u][v]==inf) puts("-1");
else printf("%d\n",dis[u][v]);
}
}

题解:洛谷P1119 灾后重建的更多相关文章

  1. 洛谷——P1119 灾后重建

    P1119 灾后重建 题目背景 B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重 ...

  2. 洛谷 P1119 灾后重建 最短路+Floyd算法

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 总结 题面 题目链接 P1119 灾后重建 题目描述 B地区在地震过后,所有村 ...

  3. 洛谷 P1119 灾后重建——dijstra

    先上一波题目 https://www.luogu.org/problem/P1119 这道题我们可以将询问按时间排序 然后随着询问将相应已经重建成功的点进行操作 每次更新一个点就以他为起点跑一遍dij ...

  4. 洛谷P1119 灾后重建[Floyd]

    题目背景 B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路才能 ...

  5. 洛谷P1119 灾后重建 Floyd + 离线

    https://www.luogu.org/problemnew/show/P1119 真是有故事的一题呢 半年前在宁夏做过一道类似的题,当时因为我的愚昧痛失了金牌. 要是现在去肯定稳稳的过,真是生不 ...

  6. 洛谷P1119 灾后重建

    传送门 题目大意:点被破坏,t[i]为第i个点修好的时间,且t[1]<t[2]<t[3].. 若干询问,按时间排序,询问第t时刻,u,v的最短路径长度. 题解:floyed 根据时间加入点 ...

  7. 洛谷P1119灾后重建——Floyd

    题目:https://www.luogu.org/problemnew/show/P1119 N很小,考虑用Floyd: 因为t已经排好序,所以逐个加点,Floyd更新即可: 这也给我们一个启发,如果 ...

  8. 洛谷 P1119 灾后重建(Floyd)

    嗯... 题目链接:https://www.luogu.org/problem/P1119 这道题是一个Floyd的很好的题目,在Floyd的基础上加一点优化: 中转点k在这里不能暴力枚举,否则会超时 ...

  9. 洛谷 [P1119] 灾后重建

    我们发现每次询问都是对于任意两点的,所以这是一道多源最短路径的题,多源最短路径,我们首先想到floyd,因为询问的时间是不降的,所以对于每次询问,我们将还没有进行松弛操作的的点k操作. #includ ...

  10. 洛谷P1119灾后重建

    题目 做一个替我们首先要明确一下数据范围,n<=200,说明n^3的算法是可以过得,而且这个题很明显是一个图论题, 所以我们很容易想到这个题可以用folyd, 但是我在做这个题的时候因为没有深刻 ...

随机推荐

  1. 使用Jackson读取xml

    找了不少,什么峰的,什么dn的参差不齐的资料,废话不少,问题是导入的包也没有.不多废话,看下面代码直接复用. package bean;import com.fasterxml.jackson.dat ...

  2. Java学习笔记2--JDK的安装和配置

    一.进入oracle官网,下载jdk oracle官网:Oracle | Cloud Applications and Cloud Platform ps:不同的浏览器,可能进入oracle官网,会只 ...

  3. JavaScript设计模式样例十六 —— 备忘录模式

    备忘录模式(Memento Pattern) 定义:保存一个对象的某个状态,以便在适当的时候恢复对象.目的:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.场景:数据缓存. ...

  4. C# 全局异常捕获(转载)

    C# 全局异常捕获 原文地址:https://www.cnblogs.com/tomahawk/articles/5993874.html 开发界有那么一个笑话,说是"「我爱你」三个字,讲出 ...

  5. gcc 和 g++ 的区别

    gcc 和 g++ 是 GNU 编译器集合(GNU Compiler Collection,简称 GCC)中的两个不同命令,用于编译 C 和 C++ 代码.尽管它们都属于同一个编译器集合,但在处理 C ...

  6. JVM学习笔记之栈区

    JVM学习笔记之栈区 本文主要内容: 栈是什么?栈帧又是什么?在JVM中,main方法调用say方法后,是怎么运行的?本文将详细讲解栈.希望大家学了之后,对栈有更深的了解. 心法:在JVM中,栈管运行 ...

  7. linux 前端部署 tomcat 脚本

    前提: 打包后的文件位置:/home/usr/back 目的部署位置:/home/usr/prod1 目的部署位置:/home/usr/prod2 在linux 服务器上 新增文件deploy-web ...

  8. 剖析 Redis List 消息队列的三种消费线程模型

    Redis 列表(List)是一种简单的字符串列表,它的底层实现是一个双向链表. 生产环境,很多公司都将 Redis 列表应用于轻量级消息队列 .这篇文章,我们聊聊如何使用 List 命令实现消息队列 ...

  9. Git Bash OpenSSL – Generate Self Signed Certificate

    前言 以前就写过了, 只是写的太乱, 这篇是一个整理版. 以前的文章: Git Bash 创建证书 PowerShell 创建证书 我已经没有用 PowerSheel 做证书了, 所以就不介绍了. 参 ...

  10. EF Core – Temporal Table 时态表

    前言 EF core 6.0 开始有 build-in 的 Temporal Table 支持了. 关于 SQL Server Temporal Table 可以看这篇. 主要参考 What's Ne ...