灾后重建(Flody应用)
灾后重建(Flody应用)
P1119 灾后重建


思路:
Q访问次数50000如果每次访问都求一次最短路毫无疑问会超时 N <= 200 可以看出Flody算法
巧妙利用条件,每个村庄重建完成时间是单调递增的,访问的时间同是单调递增,每当访问的时间大于当前村庄最大修复时间,即可把小于访问时间的所有村庄作为Flody中转点k,做一次Flody最短路。
样例输入:
4 5
1 2 3 4
0 2 1
2 3 1
3 1 2
2 1 4
0 3 5
4
2 0 2
0 1 2
0 1 3
0 1 4
样例输出:
-1
-1
5
4
代码:
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 1010, INF = 0x3f3f3f3f;
int g[N][N];
int n, m;
int vg[N];
void flody(int k)
{
	for(int i = 0; i < n; i ++ )
		for(int j = 0; j < n; j ++ )
			g[i][j] = min((LL)g[i][j], (LL)g[i][k] + (LL)g[k][j]);
} 
int main()
{
	scanf("%d %d", &n, &m);
	
	for(int i = 0; i < n; i ++ )
		cin >> vg[i];  //单调递增 
	
	memset(g, 0x3f, sizeof g);
	for(int i = 0; i <= n; i ++ ) g[i][i] = 0; 
	for(int i = 1; i <= m; i ++ )
	{
		int a, b, c;
		cin >> a >> b >> c;
		g[a][b] = g[b][a] = c;
	}
	
	int T;
	cin >> T;
	int now = 0;
	while(T -- )
	{
		int a, b, c;
		cin >> a >> b >> c;  //c单调递增 
		//若当前村庄的修复时间小于now,即作为Flody的中转点更新其他最短路. 
		while(vg[now] <= c && now <= n - 1) flody(now), now ++;
		//若访问的 a - b 的最短路已经更新即可输出 
		if(g[a][b] <= INF / 2 && vg[a] <= c && vg[b] <= c) cout << g[a][b] << endl;
		else cout << -1 << endl;
	}
	
	return 0;
}
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号