题目传送门
解题思路:
这是一道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 "); 35 continue; 36 } 37 if(g[x][y] >= 0x3f3f3f3f) printf("-1 "); 38 else 39 printf("%d ",g[x][y]); 40 } 41 return 0; 42 }