洛谷 1119 灾后重建 Floyd
比较有趣的Floyd,刚开始还真没看出来。。。。(下午脑子不太清醒)
先考虑一下Floyd本身的实现原理,
- for(k=1;k<=n;k++)
- for(i=1;i<=n;i++)
- for(j=1;j<=n;j++)
- if(e[i][j]>e[i][k]+e[k][j])
- e[i][j]=e[i][k]+e[k][j]
枚举图中的每一个点,用这些点去逐次更新当前的图,最终得到的dis值就是最终的每两点的最小距离
那么对于这道题目,我们就可以直接按照每个点修好的时间排序,按照该顺序加入点,进行Floyd,输出dis值即为结果
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 const int maxn = 500;
6 const int inf = 0x3f3f3f3f >> 1;
7 int dis[maxn][maxn];
8 int pointTime[maxn];
9 int askx[50500], asky[50500], askt[50500];
10 int n, m;
11 int tot = 0;
12 int x, y, z;
13 int q;
14 int cur = 0;
15
16 void update(int x) {
17 for (int i = 0; i < n; i++)
18 for (int j = 0; j < n; j++) {
19 dis[i][j] = std :: min(dis[i][j], dis[i][x] + dis[x][j]);
20 }
21 }
22
23 int main () {
24 scanf("%d %d", &n, &m);
25 for (int i = 0; i < n; i++)
26 scanf("%d", &pointTime[i]);
27 for (int i = 0; i < n; i++)
28 for (int j = 0; j < n; j++) {
29 if (i == j) dis[i][j] = 0;
30 else dis[i][j] = inf;
31 }
32 for (int i = 1; i <= m; i++) {
33 scanf("%d %d %d", &x, &y, &z);
34 dis[x][y] = z;
35 dis[y][x] = z;
36 }
37 scanf("%d", &q);
38 for (int i = 1; i <= q; i++) {
39 scanf("%d %d %d", &askx[i], &asky[i], &askt[i]);
40 while (pointTime[cur] <= askt[i] && cur < n) {
41 update(cur);
42 cur++;
43 }
44 if (dis[askx[i]][asky[i]] >= inf || pointTime[askx[i]] > askt[i] || pointTime[asky[i]] > askt[i]) printf("-1\n");
45 else printf("%d\n", dis[askx[i]][asky[i]]);
46 }
47
48
49 return 0;
50 }