Floyd灾后重建

Posted 行码棋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Floyd灾后重建相关的知识,希望对你有一定的参考价值。

1️⃣题目描述

题目链接:
https://www.luogu.com.cn/problem/P1119

这道题良心的是重建的时间是从小到大排序的,而且询问的重建时间也是从小到大排序的,所以我们可以正向的进行操作,不需要进行排序操作。


2️⃣简单思路

本题主要是Floyd算法本质的一个理解和练习。

Floyd算法中的k表示的是中间节点,以此为中间节点可以更新两点之间的最短距离。

f [ i ] [ j ] f[i][j] f[i][j]:代表的是ij的最短距离
每当进行一个询问时,如果有村庄在此询问的时间点之前重建完成,就要以此村庄为中转节点,对所有点的最短距离进行更新。

更新的代码:

while(a[k] <= t && k < n)

	for(int i = 0; i < n; i++)
		for(int j = 0; j < n; j++)
		
			if(f[i][k] + f[k][j] < f[i][j])
				f[j][i] = f[i][j] = f[i][k] + f[k][j];
		
	k ++;


#include<bits/stdc++.h>
using namespace std;
using ll = long long;

int main()

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m;
	cin >> n >> m;
	vector<int> a(n);
	for(int i = 0; i < n; i++) cin >> a[i];
	
	vector f(n, vector(n, 1e9));
	 	
	for(int i = 0; i < n; i++)	f[i][i] = 0;
	for(int i = 1; i <= m; i++)
	
		int a, b, c;
		cin >> a >> b >> c;
		f[a][b] = f[b][a] = c;
	
	int q;
	int k = 0;
	cin >> q;
	while(q--)
	
		int x, y, t;
		cin >> x >> y >> t;
		
		while(a[k] <= t && k < n)
		
			for(int i = 0; i < n; i++)
				for(int j = 0; j < n; j++)
				
					if(f[i][k] + f[k][j] < f[i][j])
						f[j][i] = f[i][j] = f[i][k] + f[k][j];
				
			k ++;
		
		
		if(a[x] > t || a[y] > t) cout << -1 << "\\n";
		else 
		
			if(f[x][y] == 1e9) cout << -1 << "\\n";
			else cout << f[x][y] << "\\n";
		 
		
	
	
	return 0;


以上是关于Floyd灾后重建的主要内容,如果未能解决你的问题,请参考以下文章

P1119 灾后重建 floyd

CODEVS 1817 灾后重建 Label:Floyd || 最短瓶颈路

题解灾后重建——(floyd)

Luogu P1119 灾后重建

P1119 灾后重建

Floyd灾后重建