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]:代表的是i
到j
的最短距离
每当进行一个询问时,如果有村庄在此询问的时间点之前重建完成,就要以此村庄为中转节点,对所有点的最短距离进行更新。
更新的代码:
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灾后重建的主要内容,如果未能解决你的问题,请参考以下文章