[圖論]floyed最短路(災後重建)
災後重建
Description
B地區在地震過後,所有村莊都造成了一定的損毀,而這場地震卻沒對公路造成什麽影響。但是在村莊重建好之前,所有與未重建完成的村莊的公路均無法通車。換句話說,只有連接著兩個重建完成的村莊的公路才能通車,只能到達重建完成的村莊。
給出BB地區的村莊數NN,村莊編號從00到N-1N−1,和所有MM條公路的長度,公路是雙向的。並給出第ii個村莊重建完成的時間t_iti?,你可以認為是同時開始重建並在第t_iti?天重建完成,並且在當天即可通車。若t_iti?為00則說明地震未對此地區造成損壞,一開始就可以通車。之後有QQ個詢問(x, y, t)(x,y,t),對於每個詢問你要回答在第tt天,從村莊xx到村莊y的最短路徑長度為多少。如果無法找到從xx村莊到yy村莊的路徑,經過若幹個已重建完成的村莊,或者村莊xx或村莊yy在第t天仍未重建完成 ,則需要返回-1−1。
Input
第一行包含兩個正整數N,MN,M,表示了村莊的數目與公路的數量。
第二行包含NN個非負整數t_0, t_1,…, t_{N-1}t0?,t1?,…,tN−1?,表示了每個村莊重建完成的時間,數據保證了t_0 ≤ t_1 ≤ … ≤ t_{N-1}t0?≤t1?≤…≤tN−1?。
接下來MM行,每行33個非負整數i, j, wi,j,w,ww為不超過1000010000的正整數,表示了有一條連接村莊ii與村莊jj的道路,長度為ww,保證i≠ji≠j,且對於任意一對村莊只會存在一條道路。
接下來一行也就是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天仍未修復完成,則輸出-1−1。
Examples
Input
4 5
1 2 3 4
0 2 1
2 3 1
3 1 2
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最短路(災後重建)