灾后重建(对Floyd的认识)

Posted yyys

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了灾后重建(对Floyd的认识)相关的知识,希望对你有一定的参考价值。

传送门

主要考察了对Floyd算法的认识程度(告诉我们背板子是不行的)。

Floyd,代码很简单,而其本质思想是通过其他的点进行中转来求的两点之间的最短路。因为我们知道,两点之间有多条路,如果换一条路可以缩短距离的话,就更新最短距离。而它最本质的思想,就是用其他的点进行中转,从而达到求出最短路的目的。(精辟总结摘自洛谷题解)。

对于这道题,要求得任意两点间的最短路,但是可以用来做中转点的点确实不定的。

我们可以对于每次因时间增加而加入的新的可以做中转点的点,运用Floyd的本质解题。

题目保证t0?t1?tN1?,而后面询问里给出的t也保证了t是不下降的。所以顺着加就好了。

注意:序号是从0开始的

技术图片
#include<bits/stdc++.h>
#define N 202
#define INF 2100000001
#define LL long long
using namespace std;
int read()
{
    int x=0,f=1;char s=getchar();
    while(s<0||s>9){if(s==-)f=-1;s=getchar();}
    while(s>=0&&s<=9){x=x*10+s-0;s=getchar();}
    return x*f;
}
int t[N];LL f[N][N];
int n,m;
void update(int k)
{
    for(int i=0;i<n;++i)
      for(int j=0;j<n;++j)
        if(f[i][k]+f[k][j]<f[i][j])
          f[i][j]=f[j][i]=f[i][k]+f[k][j];
}
int main()
{
    n=read(),m=read();
    for(int i=0;i<n;++i)t[i]=read();
    for(int i=0;i<n;++i)
      for(int j=i+1;j<n;++j)
      {
          if(i!=j)
          {
              f[i][j]=INF;
              f[j][i]=INF;
        }
      }
    for(int i=1;i<=m;++i)
    {
        int a=read(),b=read(),c=read();
        f[a][b]=f[b][a]=c;
    } 
    int q=read();
    int now=0;
    while(q--)
    {
        int a=read(),b=read(),time=read();
        while(t[now]<=time&&now<n)update(now),now++;
        if(t[a]>time||t[b]>time||f[a][b]==INF)printf("-1\n");
        else printf("%lld\n",f[a][b]);
    }
} 
View Code

 

以上是关于灾后重建(对Floyd的认识)的主要内容,如果未能解决你的问题,请参考以下文章

题解灾后重建——(floyd)

P1119 灾后重建 floyd

洛谷P1119 灾后重建[Floyd]

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

[Luogu P1119] 灾后重建 (floyd)

Floyd灾后重建