floyd——灾后重建(考察本质)

P1119 灾后重建 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

 

这道题太好了,之前我只会打模板,对三重循环中的第一层循环概念并没有那么清晰,没有了解floyd的本质。这道题直接让我跪了,太牛了!!

 

开始分析:

这道题的关键点在于用floyd更新任意两点距离的时候,由于每个村落修路的时间不同,不可以直接将中转点设置为0~n-1的循环。这里需要深刻理解floyd的本质,其本质是从顶点i到顶点j只能经过前k个顶点的最短距离既然是只能经过前k个点的最短距离,那么我们完全可以按照时间顺序,将该时间哪些村已经修完路的编号当作k,进行任意两点之间距离的更新。以前无脑打的模板中第一层循环k从0到n-1,而这道题抓住floyd的本质(用中转点更新最短距离),将k固定更新。不得不说一句,真是666666拉了。

 

而在q次询问之前先定义一个now的变量,用来表示该时间已经修完路的村落的编号(也就是中转点k的其中一个),当查询的时间比now对应的村落修路时间大的时候,说明此时可以将now当作中转点k进行一次floyd的更新,因为这道题村落的修路时间随编号的增加而增加,所以不用排序,直接now++,继续判断是否可以在该查询时间下将now当作k进行更新。

虽然有多次查询,但是now不用每次都初始化为0,因为修路时间递增,如果此时的now对应时间大于查询的时间,那么在之前查询时已经更新过以now作为中转点时任意两点的距离。每次now都初始化为0,耽误时间,没必要。

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=250;
 4 int dist[N][N],ti[N];
 5 int n,m,x,y,w,t;
 6 const int INF=1e9;
 7 
 8 void floyd(int k)
 9 {
10     for(int i=0;i<n;i++)
11     {
12         for(int j=0;j<n;j++)
13             dist[i][j]=dist[j][i]=min(dist[i][j],dist[i][k]+dist[k][j]);
14     }
15 }
16 
17 int main()
18 {
19     scanf("%d%d",&n,&m);
20     for(int i=0;i<n;i++)scanf("%d",&ti[i]);    //输入每个村落修路的时间
21      
22     for(int i=0;i<n;i++)    //初始化任意两点的距离 
23     {
24         for(int j=0;j<n;j++)
25         {
26             if(i==j)dist[i][j]=0;
27             else dist[i][j]=dist[j][i]=INF;
28         }
29     }
30     
31     for(int i=1;i<=m;i++)    //输入已知的两点距离 
32     {
33         scanf("%d%d%d",&x,&y,&w);
34         dist[x][y]=dist[y][x]=w;
35     }
36     
37     int q;
38     scanf("%d",&q);
39     
40     int now=0;    
41     //记录当前时间对应的编号(因为村落修路时间是递增,所以直接从第一个村落开始) 
42     while(q--)
43     {
44         scanf("%d%d%d",&x,&y,&t);
45         while(ti[now]<=t&&now<n)    
46         {//当now对应的村落修路时间小于等于t ,该村落就可以当floyd的中转点 
47             floyd(now);
48             now++;    //中转点逐渐增加 
49         }
50         
51         if(dist[x][y]==INF)printf("-1\n");
52         else if(t<max(ti[x],ti[y]))printf("-1\n");
53         else printf("%d\n",dist[x][y]);
54     }
55     
56     return 0;
57 }
View Code

 

posted @ 2022-03-01 15:17  wellerency  阅读(25)  评论(0编辑  收藏  举报