洛谷__P1119 灾后重建
题目链接:P1119 灾后重建 - 洛谷
题目大意:
-
有 N 个村庄(编号 0 到 N-1)和 M 条双向公路,每条公路有长度。
-
每个村庄有一个 重建完成时间 t[i],只有重建完成的村庄才能通车。
-
只有两个村庄都重建完成时,它们之间的公路才能通车。
-
有 Q 次询问,每次给出
(x, y, T),问在第T天时,从村庄x到村庄y的 最短路径长度。 -
如果
x或y在T天时还没重建好,或者路径不存在,则输出-1。 -
数据保证村庄的重建完成时间 t[0]≤t≤⋯≤。
-
询问中的
T是不下降的。
Floyd:
跑Floyd时,两点的最短距离要么是两点之间的连接,要么需要几个中转点来连接,
由于t[i]是升序排好了,同时询问中的 T 也是升序
直接在询问中跑Floyd,
我们直接枚举中转点,倘若中转点小于 T ,那这个中转点和后面的村庄在 T 天的时候都没有修好,直接中断即可,
同时若访问过该中转点,防止反复遍历,跳过即可
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;
const int N = 206, mod = 998244353;
int n, m, q;
int t[N];
int e[N][N];
bool v[N];
void solve() {
mst(e, 1);
cin >> n >> m;
for (int i = 0; i < n; i++) cin >> t[i];
for (int i = 0; i < m; i++) {
int a, b, c;
cin >> a >> b >> c;
e[a][b] = c, e[b][a] = c;
}
cin >> q;
while (q--) {
int a, b, c;
cin >> a >> b >> c;
for (int k = 0; k < n; k++) {
if (t[k] <= c && !v[k]) {
v[k] = true;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
e[i][j] = min(e[i][j], e[i][k] + e[k][j]);
}
}
}
}
if (t[a] <= c && t[b] <= c && e[a][b] < inf) cout << e[a][b] << endl;
else cout << -1 << endl;
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号