洛谷P1119 灾后重建 巧妙使用Floyd算法求最短路

题目链接:https://www.luogu.com.cn/problem/P1119

Floyd算法是让每一个点当中转点看能否使点到点的距离变短,本题就是根据重建时间加入中转点(不是简单的套模板,三重循环),求最短路。
如果该村庄的重建时间小于询问时间,就把这个村庄作为中转点,更新各点的最短路。
代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn=205;
const int inf=1e9+5;
int vertex[maxn][maxn];
int tim[maxn];//村庄重建时间
int n,m,q,x,y,w;
void update(int k)
{
    for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
    if((vertex[i][k]+vertex[k][j])<vertex[i][j])
    vertex[i][j]=vertex[i][k]+vertex[k][j];//更新最短路
}
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=0;i<n;i++)//编号从0开始
    scanf("%d",&tim[i]);
    for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
    vertex[i][j]=inf;//初始为无穷大
    for(int i=0;i<n;i++)
    vertex[i][i]=0;//自己到自己为0
    for(int i=0;i<m;i++)
    {
        scanf("%d %d %d",&x,&y,&w);//输入边的信息
        vertex[x][y]=vertex[y][x]=w;//无向边
    }
    scanf("%d",&q);//输入询问次数
    int now=0;
    while(q--)
    {
        int a,b,t;
        scanf("%d %d %d",&a,&b,&t);
        while(tim[now]<=t&&now<n)//如果询问时间大于未更新村庄的重建时间,继续更新。
        update(now),now++;
        if(tim[a]>t||tim[b]>t)
        puts("-1");
        else if(vertex[a][b]==inf)
        puts("-1");//无路径,输出-1
        else
        printf("%d\n",vertex[a][b]);//否则,输出答案
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44491423/article/details/104446379