luoguP1119 灾后重建

Floyd算法深刻理解

最开始只允许经过1号顶点进行中转,接下来只允许经过1和2号顶点进行中转……允许经过1~n号所有顶点进行中转,求任意两点之间的最短路程。用一句话概括就是:从i号顶点到j号顶点只经过前k号点的最短路程。

因为给的时间是不下降的序列,所以肯定要从第一个村庄开始修路,这样用时间来判断,每个村庄是否做中转的点

#include <bits/stdc++.h>
using namespace std;
const int N = 210,M = N * (N - 1) / 2 + 10,INF = 0x3f3f3f3f;
int g[N][N],n,m,times[N];
void updata(int k) {
    for(int i = 0;i < n; ++i)
        for(int j = 0;j < n; ++j)
            g[i][j] = min(g[i][j],g[i][k] + g[k][j]);
}
int main() {
    cin >> n >> m;
    for(int i = 0;i < n; ++i) cin >> times[i];
    for(int i = 0;i < n; ++i)
        for(int j = 0;j < n; ++j)
            g[i][j] = (i == j ? 0 : INF);
    for(int i = 0;i < m; ++i) {
        int a,b,c;
        cin >> a >> b >> c;
        g[a][b] = g[b][a] = min(g[a][b],c);
    }
    int q,cur = 0;
    cin >> q;
    while(q --) {
        int x,y,t;
        cin >> x >> y >> t;
        while(times[cur] <= t && cur < n) {
            updata(cur);
            cur ++;
        }
        if(times[x] > t || times[y] > t || g[x][y] == INF) cout << "-1\n";
        else cout << g[x][y] << endl;
    }
    return 0;
}
posted @ 2020-06-21 17:45  南风--  阅读(46)  评论(0编辑  收藏  举报