给定n(n<=500)个顶点,以及E(E<=10000)条边,使用迪杰斯特拉算法计算顶点s到顶点t的最短路径.第一行输入T表示有T组数据。每组数据第一行输入n、E、s、t,分别表示顶点数、边数、顶点s以及顶点t. 接下来 输入E行每行三个正整数u(1<=u<=n)、v(1<=v<=n)、w,表示顶点u到顶点v之间无向边长度w(可能有重边)。输出T行正整数,第i行表示第i组数据s到达t的最短路径长度。若s无法到达t国,输出-1.
时间: 2024-02-05 15:13:23 浏览: 117
这道题可以使用迪杰斯特拉算法求解。迪杰斯特拉算法是一种单源最短路径算法,可以求出一个节点到其他所有节点的最短路径。
具体做法如下:
1. 初始化
将起始节点s到自己的距离设置为0,其他节点到起始节点的距离设置为无穷大。将所有节点标记为未访问。
2. 更新距离
从未访问的节点中选择距离起始节点最近的节点u,并将其标记为已访问。然后更新与u相邻节点v的距离:如果通过u到达v的距离比当前已知的距离更短,则更新v的距离为通过u到达v的距离。
3. 重复步骤2
重复步骤2,直到所有节点都被访问过或者没有未访问的节点了。
4. 输出结果
输出起始节点s到每个节点的最短距离。
以下是使用C++实现的代码:
```c++
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
struct Edge {
int to, w;
};
vector<Edge> edges[505];
int dis[505];
bool vis[505];
void dijkstra(int s) {
memset(dis, INF, sizeof(dis));
memset(vis, false, sizeof(vis));
dis[s] = 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.push(make_pair(0, s));
while (!pq.empty()) {
int u = pq.top().second;
pq.pop();
if (vis[u]) continue;
vis[u] = true;
for (int i = 0; i < edges[u].size(); i++) {
int v = edges[u][i].to;
int w = edges[u][i].w;
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
pq.push(make_pair(dis[v], v));
}
}
}
}
int main() {
int T;
cin >> T;
while (T--) {
int n, E, s, t;
cin >> n >> E >> s >> t;
for (int i = 1; i <= n; i++) {
edges[i].clear();
}
for (int i = 0; i < E; i++) {
int u, v, w;
cin >> u >> v >> w;
edges[u].push_back({v, w});
edges[v].push_back({u, w});
}
dijkstra(s);
if (dis[t] == INF) {
cout << -1 << endl;
} else {
cout << dis[t] << endl;
}
}
return 0;
}
```
时间复杂度为O((n+E)logn),其中n为节点数,E为边数。
阅读全文