Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- // 使用 long long 防止路径总长度超过 int 范围(约 20 亿)
- using ll = long long;
- // 定义一个极大的数表示“无穷大”。
- // 0x3f3f3f3f3f3f3f3f 在 long long 下是一个非常大的数,
- // 且两个这样的数相加一般不会溢出,非常适合做最短路的初始值。
- constexpr ll inf = 0x3f3f3f3f3f3f3f3f;
- // Edge 结构体有两个用途:
- // 1. 在邻接表 adj 中:u 表示邻接点编号,w 表示边的权重。
- // 2. 在优先队列 q 中:u 表示节点编号,w 表示从起点 s 到 u 的当前最短距离。
- struct Edge {
- int u;
- ll w;
- // 重载小于号运算符,用于优先队列的排序。
- // C++ 的 priority_queue 默认是“大根堆”(最大值在堆顶)。
- // 我们需要“小根堆”(距离最小的在堆顶),所以这里逻辑反过来:
- // 如果当前 w 大于对方的 w,则认为优先级更低。
- bool operator< (const Edge& o) const {
- return w > o.w;
- }
- };
- int main() {
- // 关闭输入输出同步流,提高 cin/cout 的读写速度,防止 TLE(超时)
- ios::sync_with_stdio(false);
- cin.tie(nullptr);
- int n, m, s;
- cin >> n >> m >> s; // 输入点数 n,边数 m,起点 s
- // 邻接表存储图,adj[u] 存储的是从 u 出发的所有边
- vector<vector<Edge> > adj(n + 1);
- // 读入 m 条边
- for (int i = 1; i <= m; ++i) {
- int u, v;
- ll w;
- cin >> u >> v >> w;
- // 无向图,所以要双向建边
- adj[u].push_back({v, w}); // u -> v 权重 w
- adj[v].push_back({u, w}); // v -> u 权重 w
- }
- // 优先队列(小根堆),存储 pair {节点 u, 距离 w}
- // 堆顶永远是当前未确定的点中,距离起点最近的那个点
- priority_queue<Edge> q;
- // dist 数组:存储起点 s 到各个点的最短距离,初始化为无穷大
- vector<ll> dist(n + 1, inf);
- // vis 数组:标记某个点是否已经确定了最短路(是否被“出队”过)
- vector<bool> vis(n + 1, false);
- // 初始状态:起点 s 到自己的距离为 0
- q.push({s, 0});
- dist[s] = 0;
- // Dijkstra 主循环
- while (!q.empty()) {
- // 取出堆顶元素(当前距离起点最近的点)
- Edge now = q.top();
- q.pop();
- int u = now.u; // 当前节点编号
- // 如果该点已经被访问过(即已经确定了最短路),则跳过。
- // 这是因为同一个点可能多次入队(每次发现更短路径都会入队),
- // 只有第一次出队时的距离才是最短的。
- if (vis[u])
- continue;
- // 标记该点已确定最短路
- vis[u] = true;
- // 遍历 u 的所有邻接点(扫描出边)
- for (int i = 0; i < adj[u].size(); ++i) {
- int v = adj[u][i].u; // 邻接点 v
- ll w = adj[u][i].w; // 边 u-v 的权重
- // 松弛操作 (Relaxation):
- // 如果经由 u 到达 v 的距离(dist[u] + w)比当前记录的 dist[v] 更短
- if (dist[v] > dist[u] + w) {
- dist[v] = dist[u] + w; // 更新 v 的最短距离
- q.push({v, dist[v]}); // 将更新后的 v 放入队列,以便后续扩展
- }
- }
- }
- // 输出从起点 s 到所有点 1~n 的最短距离
- for (int i = 1; i <= n; ++i) {
- cout << dist[i] << " ";
- }
- cout << "\n";
- return 0;
- }
Advertisement