luogu P1119 灾后重建

传送门

突然想起第一次讲课的时候说错了floyd的事...

当时LZY还在然后被直接打脸就很爽

也不知道这一次自己能不能剩下来 又会有多少人走掉

 

这题利用了floyd的滚动数组优化掉的那一维 也就是f[k][i][j]表示中间点仅有前k个时i->j的最短路

所以按时间排序直接做floyd 然后如果有询问就做了 所以要离线

(貌似输入按时间排好序了不用离线)

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<queue>
 6 #include<vector>
 7 #include<iostream>
 8 #include<iomanip>
 9 #define itn int
10 #define ms(a,b) memset(a,b,sizeof a)
11 #define rep(i,a,n) for(int i = a;i <= n;i++)
12 #define per(i,n,a) for(int i = n;i >= a;i--)
13 #define inf 2147483647
14 using namespace std;
15 typedef long long ll;
16 ll read() {
17     ll as = 0,fu = 1;
18     char c = getchar();
19     while(c < '0' || c > '9') {
20         if(c == '-') fu = -1;
21         c = getchar();
22     }
23     while(c >= '0' && c <= '9') {
24         as = as * 10 + c - '0';
25         c = getchar();
26     }
27     return as * fu;
28 }
29 //head
30 const int N = 806;
31 int n,m,Q;
32 int t[N];
33 int dp[N][N];
34 void add(int x,int y) {
35     dp[x][y] = dp[y][x] = read();
36 }
37 
38 void Floyd(int k) {
39     rep(i,1,n) rep(j,1,n) {
40         dp[i][j] = min(dp[i][j],dp[i][k] + dp[k][j]);
41     }
42 }
43 
44 int main() {
45     n = read(),m = read();
46     ms(dp,63);
47     rep(i,1,n) t[i] = read(),dp[i][i] = 0;
48     rep(i,1,m) add(read()+1,read()+1);
49     Q = read();
50     int cur = 1;
51     //[1,cur)
52     while(Q--) {
53         int x = read()+1,y = read()+1,tim = read();
54         while(cur <= n && t[cur] <= tim) Floyd(cur++);
55         if(t[x] > tim || t[y] > tim || dp[x][y] == dp[0][0]) puts("-1");
56         else printf("%d\n",dp[x][y]);
57     }
58     return 0;
59 }

 

posted @ 2018-11-08 15:01  白怀潇  阅读(118)  评论(0编辑  收藏  举报