P1119 reconstruction · Shortest Floyd

answer

An in-depth understanding of the nature of the subject Floyd
Floyd essence of: obtaining from the i-th vertex to vertex number j via the shortest path just before the k number of vertices
in this question, the order of time (because t is not reduced) updated every a point available for the most short-circuited,
corresponds exactly thinking Floyd algorithm: calculated vertex to vertex x k y front within the shortest time
big brother blog, really great, must see


Here Insert Picture Description


#include <bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;//不可以使用1e9 爆范围了
const int N=1e3+10;
int t[N],f[N][N];//重建时间 两点之间的距离
int n,m,u,v,c;

void update(int k){
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            //if(i==j||i==k||k==j)continue;
            /*
                if(f[i][k]!=INF && f[k][j]!=INF && t[i]<=k && t[j]<=k) 这个写法是错的
                假如B的重建时间晚于A 那么在用A更新各个点的时候就会跳过B
                当用B更新各个点的时候就无法得知AB之间的距离 从而出现差错

                所以写Floyd时 这一段是不可以更改的
            */
             if(f[i][k]!=INF && f[k][j]!=INF)
                f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
        }
    }
}
int main()
{
    memset(f, INF, sizeof f);

    cin>>n>>m;
    for (int i = 0 ; i < n; i++) {
        f[i][i]=0;
        cin>>t[i];
    }
    for (int i = 1; i <= m; i++) {
        cin>>u>>v>>c;
        f[u][v]=f[v][u]=c;
    }

    int que;
    int now=0;//村庄的编号
    cin>>que;
    for (int i = 1; i <= que; i++) {
        cin>>u>>v>>c;

        while(now<n && t[now]<=c){//找到已经重建号的前k个村庄 题目说了 村庄修建时间是从小到大的
            update(now);
            ++now;
        }

        if(f[u][v]!=INF && t[u]<=c && t[v]<=c) printf("%d\n", f[u][v]);
        else puts("-1");
    }
    return 0;
}
Published 43 original articles · won praise 0 · Views 1260

Guess you like

Origin blog.csdn.net/Yubing792289314/article/details/104019573