1. 程式人生 > >[圖論]floyed最短路(災後重建)

[圖論]floyed最短路(災後重建)

之前 兩個 pst 什麽 C4D sin 短路徑 string 重建

災後重建

Description

B地區在地震過後,所有村莊都造成了一定的損毀,而這場地震卻沒對公路造成什麽影響。但是在村莊重建好之前,所有與未重建完成的村莊的公路均無法通車。換句話說,只有連接著兩個重建完成的村莊的公路才能通車,只能到達重建完成的村莊。

給出BB地區的村莊數NN,村莊編號從00到N-1N1,和所有MM條公路的長度,公路是雙向的。並給出第ii個村莊重建完成的時間t_iti?,你可以認為是同時開始重建並在第t_iti?天重建完成,並且在當天即可通車。若t_iti?00則說明地震未對此地區造成損壞,一開始就可以通車。之後有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}t0?t1?tN1?

接下來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

[圖論]floyed最短路(災後重建)