问题描述
询问次数 5 000 00, 顶点数 200
怎么办?
dijkstra?对不起,超时了/。
时间限制是1秒,询问5 000 00 ,每次dijsktra要跑n*n*logm 次,稳稳超时
仔细想想就可以发现,没必要次次都跑一次最短路么,上一次结果能保留下来!!!
多源最短路Floyd?,但是它O(n^3)啊?
诚然,Floyd比dijstra看起来慢,但是少用几次就快了啊!
每次只绕k抄近路,巧妙避开了k之外的路!!!
相信聪明的你已经知道如何写这个题了!
好了就这样了
#include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<vector> using namespace std; #define maxn 310 const int INF = 0x3f3f3f3f; int map[maxn][maxn]; int n, m, Q; int update(int k) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { map[i][j] = min(map[i][j], map[i][k] + map[k][j]); } } return 0; } int vis[maxn]; int list[maxn]; int main() { scanf("%d %d", &n, &m); for (int i = 0; i < n; i++) { scanf("%d", &list[i]); } int be, en, len; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) map[i][j] = INF; for (int i = 0; i < n; i++) map[i][i] = 0; while (m--) { scanf("%d %d %d", &be, &en, &len); map[be][en] = len; map[en][be] = len; } scanf("%d", &Q); int t; while (Q--) { scanf("%d %d %d", &be, &en, &t); for (int i = 0; i < n; i++){//寻找新的修好的城市 if (list[i] <= t) { if (vis[i] == 1) vis[i] = -1;//早就修好的城市一边去,不用计算了 if (vis[i] == 0) vis[i] = 1; } } for (int i = 0; i < n; i++) if (vis[i] == 1) update(i); if (map[be][en] == INF || vis[be] == 0 || vis[en] == 0) printf("-1 "); else printf("%d ", map[be][en]); } return 0; }
我永远喜欢新垣结衣 ❤❤❤❤❤❤❤