1. 程式人生 > >[洛谷P1119]災後重建

[洛谷P1119]災後重建

inline int tar etc 時間 超時 ++i ostream fine

原題傳送門

這道題是個好題,至少我第一下沒有想到是一個古老的算法:$Floyd$

第一眼知道是個最短路,然後就很果斷的寫了$dijkstra$,對於每組輸入求一遍最短路,發現時間很困難。又該寫了$SPFA$。當時認為$SPFA$在新加入村莊時只需將其松弛操作即可。

後來發現超時,$80pts$。

事實上在維護新加入的村莊時計算最短路,$Floyd$在這方面很出色。$Floyd$滿足三角不等式,即$i$到$j$借助新加入的村莊$k$進行維護,而且只需$O(n^2)$

綜上,復雜度為$O(n^3)$。

 1 #include <iostream>
 2 #include <cstdio>
 3
#include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 8 #define re register 9 #define rep(i, a, b) for (re int i = a; i <= b; ++i) 10 #define repd(i, a, b) for (re int i = a; i >= b; --i) 11 #define maxx(a, b) a = max(a, b); 12 #define minn(a, b) a = min(a, b); 13
#define LL long long 14 #define inf (1 << 30) 15 16 inline int read() { 17 int w = 0, f = 1; char c = getchar(); 18 while (!isdigit(c)) f = c == - ? -1 : f, c = getchar(); 19 while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ 0), c = getchar(); 20 return w * f;
21 } 22 23 const int maxn = 200 + 5; 24 25 int dis[maxn][maxn], n, m, q, t[maxn]; 26 27 int main() { 28 memset(dis, 0x3f, sizeof(dis)); 29 30 n = read(), m = read(); 31 32 rep(i, 0, n-1) t[i] = read(); 33 34 rep(i, 1, m) { 35 int u = read(), v = read(); 36 dis[u][v] = dis[v][u] = read(); 37 } 38 39 q = read(); 40 41 int k = 0; 42 43 rep(kase, 1, q) { 44 int x = read(), y = read(), T = read(); 45 while (k < n && T >= t[k]) { 46 rep(i, 0, n-1) 47 rep(j, 0, n-1) 48 if (i != k && j != k) minn(dis[i][j], dis[i][k] + dis[k][j]); 49 k++; 50 } 51 if (t[x] > T || t[y] > T || dis[x][y] == 1061109567) printf("-1\n"); 52 else printf("%d\n", dis[x][y]); 53 } 54 55 return 0; 56 }

[洛谷P1119]災後重建