1. 程式人生 > >luogu P1119 災後重建

luogu P1119 災後重建

efi 如果 tps 排序 直接 problem inf main 傳送門

傳送門

突然想起第一次講課的時候說錯了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 }

luogu P1119 災後重建