洛谷 P1119 灾后重建(Floyd)

嗯...

 

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

这道题是一个Floyd的很好的题目,在Floyd的基础上加一点优化:

中转点k在这里不能暴力枚举,否则会超时,我们则可以用时间的限制来优化一下,用一个while,只有中转站被修复(即中转站修复时间小于t)时,k才能作为中转站,也就是指枚举在t时,被修复了的中转站,这样时间复杂度会降低一些...

 

本题细节问题:

1.每个村庄的下标是从0开始的

2.因为memset比较神奇,所以最后判-1时,要找一个比0x3f的数大的数进行判断,并且是>=

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 
 7 int g[205][205], a[20005], n, m;
 8 
 9 inline void update(int k){
10     for(int i = 0; i < n; i++){
11         for(int j = 0; j < n; j++){
12             g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
13         }
14     }
15     return;
16 }
17 
18 int main(){
19     memset(g, 0x3f, sizeof(g));
20     scanf("%d%d", &n, &m);
21     for(int i = 0; i < n; i++) {scanf("%d", &a[i]); g[i][i] = 0;}//枚举细节 
22     for(int i = 1; i <= m; i++) {
23         int x, y, z;
24         scanf("%d%d%d", &x, &y, &z);
25         g[x][y] = g[y][x] = z;
26     }
27     int q, now = 0;
28     scanf("%d", &q);
29     for(int i = 1; i <= q; i++) {    
30         int u, v, t;
31         scanf("%d%d%d", &u, &v, &t);  
32         while(a[now] <= t && now < n){
33             update(now);
34             now++;
35         }
36         if(g[u][v] >= 0x3f3f3f3f || a[u] > t || a[v] > t) printf("-1
");
37         else printf("%d
", g[u][v]);
38     }
39     return 0;
40 }
AC代码
原文地址:https://www.cnblogs.com/New-ljx/p/11262382.html