[图论]floyed最短路(灾后重建)

灾后重建

Description

B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响。但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车。换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄。

给出BB地区的村庄数NN,村庄编号从00到N-1N1,和所有MM条公路的长度,公路是双向的。并给出第ii个村庄重建完成的时间t_iti,你可以认为是同时开始重建并在第t_iti天重建完成,并且在当天即可通车。若t_iti00则说明地震未对此地区造成损坏,一开始就可以通车。之后有QQ个询问(x, y, t)(x,y,t),对于每个询问你要回答在第tt天,从村庄xx到村庄y的最短路径长度为多少。如果无法找到从xx村庄到yy村庄的路径,经过若干个已重建完成的村庄,或者村庄xx或村庄yy在第t天仍未重建完成 ,则需要返回-11。

Input

第一行包含两个正整数N,MN,M,表示了村庄的数目与公路的数量。

第二行包含NN个非负整数t_0, t_1,…, t_{N-1}t0,t1,,tN1,表示了每个村庄重建完成的时间,数据保证了t_0 ≤ t_1 ≤ … ≤ t_{N-1}t0t1tN1

接下来MM行,每行33个非负整数i, j, wi,j,w,ww为不超过1000010000的正整数,表示了有一条连接村庄ii与村庄jj的道路,长度为ww,保证i≠jij,且对于任意一对村庄只会存在一条道路。

接下来一行也就是M+3M+3行包含一个正整数QQ,表示QQ个询问。

接下来QQ行,每行33个非负整数x, y, tx,y,t,询问在第tt天,从村庄xx到村庄yy的最短路径长度为多少,数据保证了tt是不下降的。

output

QQ行,对每一个询问(x, y, t)(x,y,t)输出对应的答案,即在第tt天,从村庄xx到村庄yy的最短路径长度为多少。如果在第t天无法找到从xx村庄到yy村庄的路径,经过若干个已重建完成的村庄,或者村庄x或村庄yy在第tt天仍未修复完成,则输出-11。

Examples

Input

4 5
1 2 3 4
0 2 1
2 3 1
3 1 2
2 1 4
0 3 5
4
2 0 2
0 1 2
0 1 3
0 1 4

Output

-1
-1
5
4

正确解法:

正解是floyed,因为数据量只有200

我刚开始想的是按边排序,然后按时间这样子一个个输入边,在floyed一边

成功的tle

后来看题解。只要把边全部输入就好了,然后看时间,如果时间到了就更新一遍。

加了一个特判。

哦我在想 提前输入边会不会对后面有影响。其实是没有影响的。

如果这个村庄没有的话,直接输出 -1 ,如果有的话,就可以直接floyed了

时间是单调递增的,这个先floyed了,后面只会在更新后面的点,对前面则没有影响。

 1 #include "pch.h"
 2 #pragma warning(disable:4996)
 3 #include<iostream>
 4 #include<cstdio>
 5 #include<string>
 6 #include<cstring>
 7 #include<map>
 8 #include<set>
 9 #include<vector>
10 #include<queue>
11 #include<algorithm>
12 #include<cmath>
13 using namespace std;
14 typedef long long ll;
15 const int inf = 0x7fffffff;
16 const int N = 200 + 10;
17 const int M = 20000;
18 int n, m,q,now=0;
19 int xx, yy, tt;
20 int a[N][N],tim[N];
21 void init()
22 {
23     scanf("%d %d",&n,&m);
24     for(int i=0;i<n;i++)
25         for (int j = 0; j < n; j++)
26         {
27             if (i == j)    a[i][j] = 0;
28             else a[i][j] = inf;
29         }
30     for (int i = 0; i < n; i++)
31         scanf("%d",&tim[i]);
32     while (m--)
33     {
34         scanf("%d %d %d",&xx,&yy,&tt);
35         a[xx][yy] = tt;
36         a[yy][xx] = tt;
37     }
38 }
39 void floyed(int k)
40 {
41     for (int i = 0; i < n; i++)
42         for (int j = 0; j < n; j++)
43             if (a[i][k] != inf && a[k][j] != inf)
44                 if (a[i][j] > a[i][k] + a[k][j])
45                     a[i][j] = a[i][k] + a[k][j];
46 }
47 int main()
48 {
49     init();
50     scanf("%d",&q);
51     while (q--)
52     {
53         scanf("%d %d %d",&xx,&yy,&tt);
54         while (tt >= tim[now] && now < n)
55         {
56             floyed(now);
57             now++;
58         }
59         if (tim[xx] > tt || tim[yy] > tt)
60             printf("-1\n");
61         else
62         {
63             if (a[xx][yy] == inf)
64                 printf("-1\n");
65             else printf("%d\n", a[xx][yy]);
66         }
67     }
68 
69     return 0;
70 }
View Code

猜你喜欢

转载自www.cnblogs.com/Kaike/p/10497719.html