1 2 3 4

洛谷p1119--灾难后重建(Floyd不仅仅是板子)

问题描述

询问次数  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\n");
		else printf("%d\n", map[be][en]);
	}
	return 0;
}

 我永远喜欢新垣结衣 ❤❤❤❤❤❤❤

posted @ 2019-08-24 14:57  Lesning  阅读(140)  评论(0编辑  收藏  举报