Luogu P1119 灾后重建

传送门

这道题一眼看上去...Floyd..?

每个村庄修复时间、询问都是不下降的...似乎连排序都省略了x

既然这样,那每次询问时,更新这个询问之前的村庄来求目前的最短路径就可以了

注意事项:对于这个循环

for(; t[k] <= z && k < n; k++) {
            f[k] = true;
            floyd(k);
        }

1.k不能定义为for内部的局部变量(因为之前的村庄已经遍历过了不需要再走一遍)

(否则时间复杂度会从O(n^3)变为O(q*n^3))

2.注意判断边界(k < n),否则当询问时间超出最后一个村庄的修复时间时就会陷入循环x

代码如下

#include<cstdio>
#include<iostream>
using namespace std;

const int INF = 100005;
const int maxn = 205;
int n,m,q,x,y,z,k;
int t[maxn],dis[maxn][maxn],ans[maxn][maxn];
bool f[maxn];

void floyd(int k) {
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
            {
                dis[i][j] = min(dis[i][j],dis[i][k]+dis[k][j]);
                ans[i][j] = min(ans[i][j],dis[i][j]);
            }
}

int main() {
    scanf("%d%d",&n,&m);
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++) {
            dis[i][j] = INF;
            ans[i][j] = INF;
            if(i == j)dis[i][j] = 0;
        }
    for(int i = 0; i < n; i++)
        scanf("%d",&t[i]);
    for(int i = 0; i < m; i++) {
        scanf("%d%d%d",&x,&y,&z);
        dis[x][y] = z;
        dis[y][x] = z;
    }
    scanf("%d",&q);
    for(int i = 0; i < q; i++) {
        scanf("%d%d%d",&x,&y,&z);
        for(; t[k] <= z && k < n; k++) {
            f[k] = true;
            floyd(k);
        }
        if(ans[x][y] == INF || !f[x] || !f[y])printf("-1\n");
        else printf("%d\n",ans[x][y]);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/mogeko/p/10063578.html

时间: 2024-08-17 22:59:29

Luogu P1119 灾后重建的相关文章

[Luogu P1119] 灾后重建 (floyd)

题面 传送门:https://www.luogu.org/problemnew/show/P1119 Solution 这题的思想很巧妙. 首先,我们可以考虑一下最暴力的做法,对每个时刻的所有点都求一遍单元最短路 因为最多只有200个时刻,时间复杂度为O(n^3log(n+m))) (堆优化的迪杰斯特拉) 显然对于n=200,并过不了 我们可有进一步分析 这一题,我们堆优化的迪杰斯特拉慢在每加入一个点,我们每一次都得对全图彻彻底底做一轮松弛 那换个角度考虑,如果我只松弛经过新加入的点的点对呢?

洛谷P1119 灾后重建(floyd)

P1119 灾后重建 题目背景 B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄. 题目描述 给出B地区的村庄数N,村庄编号从0到N-1,和所有M条公路的长度,公路是双向的.并给出第i个村庄重建完成的时间t[i],你可以认为是同时开始重建并在第t[i]天重建完成,并且在当天即可通车.若t[i]为0则说明地震未对此地区造成损坏,一

P1119 灾后重建

P1119 灾后重建 题目背景 B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄. 题目描述 给出B地区的村庄数N,村庄编号从0到N-1,和所有M条公路的长度,公路是双向的.并给出第i个村庄重建完成的时间t[i],你可以认为是同时开始重建并在第t[i]天重建完成,并且在当天即可通车.若t[i]为0则说明地震未对此地区造成损坏,一

洛谷——P1119 灾后重建

https://www.luogu.org/problem/show?pid=1119 题目背景 B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄. 题目描述 给出B地区的村庄数N,村庄编号从0到N-1,和所有M条公路的长度,公路是双向的.并给出第i个村庄重建完成的时间t[i],你可以认为是同时开始重建并在第t[i]天重建完成,

[最短路]P1119 灾后重建

题目背景 B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄. 题目描述 给出B地区的村庄数N,村庄编号从0到N-1,和所有M条公路的长度,公路是双向的.并给出第i个村庄重建完成的时间t[i],你可以认为是同时开始重建并在第t[i]天重建完成,并且在当天即可通车.若t[i]为0则说明地震未对此地区造成损坏,一开始就可以通车.之后有

P1119 灾后重建 floyd

题目背景 BB地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄. 题目描述 给出BB地区的村庄数NN,村庄编号从00到N-1N−1,和所有MM条公路的长度,公路是双向的.并给出第ii个村庄重建完成的时间t_iti?,你可以认为是同时开始重建并在第t_iti?天重建完成,并且在当天即可通车.若t_iti?为00则说明地震未对此地区造

灾后重建「解题报告」

P1119 灾后重建 Luogu P1119 题意 有n个村庄m条路,每个村庄都被地震摧毁,在某一时刻 \(t_i\)被修好.对于某条路,只有当它连接的两个村庄都被修好后才能通过.有q个询问,询问在某一时刻两村庄间的最短路. 第一行包含两个正整数 \(n,m\) . 第二行包含 \(n\) 个非负整数 \(t_0, t_1,-, t_{N-1}\),表示每个村庄重建完成的时间,数据保证了 \(t_0 ≤ t_1 ≤ - ≤ t_{N-1}\) 接下来 \(m\) 行,每行3个非负整数 \(i,j

AC日记——灾后重建 洛谷 P1119

灾后重建 思路: 看到n<=200,思考弗洛伊德算法: 如何floyed呢? floyed是一种动态规划求最短路的算法: 它通过枚举中间点来更新两点之间最短路: 回到这个题本身: 所有点的重建完成的时间和询问的时间都已经排好序了: 所以,我们把floyed拆开: 对于一个三维的k,i,j的floyed算法: 我们判断当前的询问在哪两个相邻的k之间: 然后,我们判断当时的连通性以及最短路情况: 来,上代码: #include <cstdio> #include <cstring>

CODEVS 1817 灾后重建 Label:Floyd || 最短瓶颈路

描述 灾后重建(rebuild)  B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄.  给出B地区的村庄数N,村庄编号从0到N-1,和所有M条公路的长度,公路是双向的.并给出第i个村庄重建完成的时间t[i],你可以认为是同时开始重建并在第t[i]天重建完成,并且在当天即可通车.若t[i]为0则说明地震未对此地区造成损坏,一开始