乌拉拉市有n个共享电车桩点和m条双向道路,第 i 条道路连接 a i 和 b i ,长度为 c i 单位距离。计算鸭每次使用一辆共享电车可以行驶 L 单位距离。更换共享电车只能在n个共享电车桩点更换,不能在路上更换,因为路上没有共享电车桩点。 现在计算鸭现在在规划行程,他有 q 个问题想要问你,第 i 个问题是:在s i 点扫码租一辆共享电车后,想要到达t i ,路途中,计算鸭最少需要更换几次共享电车,如果无法到达就是 −1。第一行输入三个整数 n,m,L,含义如题所示 接下来 m 行,每行输入三个正整数 a i ,b i ,c i ,含义如题所示 然后在一行中输入一个正整数 q,代表询问的次数 最后 q 行,每行输入两个正整数 s i ,t i ,含义如题所示 2≤n≤300 0≤m≤ 2 n×(n−1) 1≤a i ,b i ,s i ,t i ≤n 1≤L,c i ≤10 9 1≤q≤n×(n−1) 输入保证无重边和自环; 询问中 s i =t i 输出共 q 行,第 i 行代表第 i 次询问的结果。给出C++代码
时间: 2024-02-01 13:02:09 浏览: 233
```
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 310;
const ll inf = 1e18;
int n, m, q;
ll L, dis[N][N];
struct Edge {
int from, to;
ll w;
Edge(int a = 0, int b = 0, ll c = 0): from(a), to(b), w(c) {}
};
vector<Edge> edges;
vector<int> G[N];
void addEdge(int u, int v, ll w) {
edges.push_back(Edge(u, v, w));
int m = edges.size();
G[u].push_back(m - 1);
}
void floyd() { // 预处理任意两点之间的最短路
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
dis[i][j] = (i == j ? 0 : inf);
}
}
for (int i = 0; i < edges.size(); ++i) {
int u = edges[i].from, v = edges[i].to;
dis[u][v] = dis[v][u] = min(dis[u][v], edges[i].w);
}
for (int k = 1; k <= n; ++k) {
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
}
}
}
}
int main() {
scanf("%d%d%lld", &n, &m, &L);
for (int i = 1; i <= m; ++i) {
int u, v;
ll w;
scanf("%d%d%lld", &u, &v, &w);
addEdge(u, v, w);
addEdge(v, u, w);
}
floyd(); // 预处理任意两点之间的最短路
scanf("%d", &q);
while (q--) {
int s, t;
scanf("%d%d", &s, &t);
if (dis[s][t] > L) { // 如果直接走超过了L,无法到达
printf("-1\n");
continue;
}
int ans = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < G[i].size(); ++j) {
int k = edges[G[i][j]].to;
if (dis[s][i] + edges[G[i][j]].w + dis[k][t] <= L) { // 如果从i到k再到t的距离小于等于L,则可以不用换电车
ans = max(ans, 1);
} else { // 否则需要在i处换电车
ans = max(ans, 2);
}
}
}
printf("%d\n", ans);
}
return 0;
}
```
阅读全文