洛谷 P1119 灾后重建(Floyd)

题目传送门

解题思路:

这是一道floyed的题。但是有所不同的是,这道题里的点是有时间限制的。

所以说我们在做floyed的时候,我们不能直接枚举所有中转点,而是按照时间来进行。

以及,有可能出现询问的时候两个点没有修好,我们还要判断这个。

而且在这道题里,询问的t是不下降的,这样我们就不用考虑数组的问题。我们在上一次询问时的更新,一定是合法的。

当然,因为询问和修复都是有时间的,所以说我们要在读完修复后。

//感谢simex大佬的思路,友链里有

AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 
 7 int n,m,g[201][201],t[201],q,k;
 8 bool vis[201];
 9 int x,y,v;
10 
11 int main() {
12     memset(g,0x3f,sizeof(g));
13     scanf("%d%d",&n,&m);
14     for(int i = 0;i < n; i++) 
15         scanf("%d",&t[i]);
16     for(int i = 1;i <= m; i++) {
17         scanf("%d%d%d",&x,&y,&v);
18         g[x][y] = v;g[y][x] = v;
19     }
20     for(int i = 0;i < n; i++)
21         g[i][i] = 0;
22     scanf("%d",&q);
23     for(int a = 1;a <= q; a++) {
24         scanf("%d%d%d",&x,&y,&v);
25         for(k;k < n; k++) {
26             if(t[k] > v) break;
27             else {
28                 for(int i = 0;i < n; i++)
29                     for(int j = 0;j < n; j++) 
30                         g[j][i] = g[i][j] = min(g[i][j],g[i][k] + g[k][j]);
31             }
32         }
33         if(t[x] > v || t[y] > v) {
34             printf("-1\n");
35             continue;
36         }
37         if(g[x][y] >= 0x3f3f3f3f) printf("-1\n");
38         else
39             printf("%d\n",g[x][y]);
40     }
41     return 0;
42 }

猜你喜欢

转载自www.cnblogs.com/lipeiyi520/p/11256709.html