
例题https://www.luogu.com.cn/problem/P1339
朴素dijkstra (邻接表)
| dijkstra 正确性来自于贪心 也就是st数组内的数(dist) 必须逐渐变大这样才能保证后面的数更新的时候,当前的第三边dist[t]都是最小值 [详见](https: |
dist[x]表示 x到start 的最短距离
| #include <iostream> |
| #include <cstring> |
| #include <algorithm> |
| |
| |
| using namespace std; |
| |
| const int N = 2510, M = 6220 * 2; |
| |
| int h[N], w[M], ne[M], e[M], idx; |
| int n, m, start, ened; |
| bool st[N]; |
| int dist[N]; |
| |
| void add(int a, int b, int c) |
| { |
| e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ; |
| } |
| |
| int dijkstra() |
| { |
| dist[start] = 0; |
| int k = n; |
| while (k -- ) |
| { |
| int t = -1; |
| for (int i = 1; i <= n; i ++ ) |
| if (!st[i] && (t == -1 || dist[t] > dist[i])) |
| t = i; |
| |
| st[t] = true; |
| |
| for (int i = h[t]; i != -1; i = ne[i]) |
| { |
| int j = e[i]; |
| dist[j] = min(dist[j], dist[t] + w[i]); |
| } |
| } |
| |
| return dist[ened]; |
| } |
| |
| int main() |
| { |
| cin >> n >> m >> start >> ened; |
| memset(h, -1, sizeof h); |
| memset(dist, 0x3f, sizeof dist); |
| while (m -- ) |
| { |
| int a, b, c; |
| scanf("%d%d%d", &a, &b, &c); |
| add(a, b, c); |
| add(b, a, c); |
| } |
| |
| cout << dijkstra(); |
| |
| return 0; |
| } |
朴素dijkstra 邻接矩阵
| #include <iostream> |
| #include <cstring> |
| #include <algorithm> |
| |
| |
| using namespace std; |
| |
| const int N = 3510; |
| |
| int g[N][N]; |
| int n, m, start, ened; |
| bool st[N]; |
| int dist[N]; |
| |
| |
| int dijkstra() |
| { |
| dist[start] = 0; |
| int k = n; |
| |
| while (k -- ) |
| { |
| int t = -1; |
| for (int i = 1; i <= n; i ++ ) |
| if (!st[i] && (t == -1 || dist[t] > dist[i])) |
| t = i; |
| |
| st[t] = true; |
| |
| for (int i = 1; i <= n; i ++ ) |
| dist[i] = min(dist[i], dist[t] + g[t][i]); |
| } |
| |
| return dist[ened]; |
| } |
| |
| int main() |
| { |
| cin >> n >> m >> start >> ened; |
| memset(dist, 0x3f, sizeof dist); |
| memset(g, 0x3f, sizeof g); |
| while (m -- ) |
| { |
| int a, b, c; |
| scanf("%d%d%d", &a, &b, &c); |
| g[a][b] = min(g[a][b], c); |
| g[b][a] = min(g[b][a], c); |
| } |
| |
| cout << dijkstra(); |
| |
| return 0; |
| } |
堆优化dijkstra
| #include <iostream> |
| #include <algorithm> |
| #include <cstring> |
| #include <queue> |
| |
| using namespace std; |
| |
| typedef pair<int, int> PII; |
| |
| const int N = 2510, M = 6550 * 2; |
| |
| int h[N], ne[M], e[M], w[M], idx; |
| int dist[N]; |
| bool st[N]; |
| int n, m, S, T; |
| |
| void add(int a, int b, int c) |
| { |
| e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ; |
| } |
| |
| int dijkstra() |
| { |
| priority_queue<PII, vector<PII>, greater<PII>> q; |
| q.push({0, S}); |
| dist[S] = 0; |
| while (q.size()) |
| { |
| auto t = q.top(); |
| q.pop(); |
| int ver = t.second, distance = t.first; |
| if (st[ver]) continue; |
| st[ver] = true; |
| |
| for (int i = h[ver]; i != -1; i = ne[i]) |
| { |
| int j = e[i]; |
| if (dist[j] > distance + w[i]) |
| { |
| dist[j] = distance + w[i]; |
| q.push({dist[j], j}); |
| } |
| } |
| } |
| return dist[T]; |
| } |
| |
| int main() |
| { |
| cin >> n >> m >> S >> T; |
| memset(h, -1, sizeof h); |
| memset(dist, 0x3f, sizeof dist); |
| while (m -- ) |
| { |
| int a, b, c; |
| cin >> a >> b >> c; |
| add(a, b, c); |
| add(b, a, c); |
| } |
| |
| cout << dijkstra(); |
| return 0; |
| } |
spfa
我更新过谁,我再拿被更新的这个更新别人。
| |
| |
| |
| |
| using namespace std; |
| |
| const int N = 2510, M = 6210 * 2; |
| |
| int h[N], ne[M], e[M], idx, w[M]; |
| int n, m, S, T; |
| int dist[N]; |
| int q[N]; |
| bool st[N]; |
| |
| void add(int a, int b, int c) |
| { |
| e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ; |
| } |
| |
| |
| int spfa() |
| { |
| int tt = 1, hh = 0; |
| q[hh] = S; |
| dist[S] = 0; |
| |
| while (hh != tt) |
| { |
| int t = q[hh ++ ]; |
| if (hh == N) hh = 0; |
| st[t] = false; // 退出队列后还有可能进来 |
| |
| for (int i = h[t]; i != -1; i = ne[i]) |
| { |
| int j = e[i]; |
| if (dist[j] > dist[t] + w[i]) |
| { |
| dist[j] = dist[t] + w[i]; |
| if (!st[j]) // 保证队列中这个点只有一个 |
| { |
| q[tt ++ ] = j; |
| if (tt == N) tt = 0; |
| st[j] = true; |
| } |
| } |
| } |
| } |
| |
| return dist[T]; |
| } |
| int main() |
| { |
| cin >> n >> m >> S >> T; |
| memset(h, -1, sizeof h); |
| memset(dist, 0x3f, sizeof dist); |
| while (m -- ) |
| { |
| int a, b, c; |
| cin >> a >> b >> c; |
| add(a, b, c); |
| add(b, a, c); |
| } |
| |
| cout << spfa(); |
| |
| return 0; |
| } |
bellman_ford
| #include <iostream> |
| #include <cstring> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| const int N = 2510, M = 6500 * 2; |
| |
| |
| int h[N], ne[M], e[M], w[M], idx; |
| int dist[N]; |
| bool st[N]; |
| int n, m, S, T; |
| |
| |
| void add(int a, int b, int c) |
| { |
| e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ; |
| } |
| int bellman_ford() |
| { |
| int k = n; |
| dist[S] = 0; |
| while (k -- ) |
| { |
| int backup[N]; |
| memcpy(backup, dist, sizeof dist); |
| for (int i = 1; i <= n; i ++ ) |
| for (int j = h[i]; j != -1; j = ne[j]) |
| dist[e[j]] = min(dist[e[j]], backup[i] + w[j]); |
| } |
| |
| return dist[T]; |
| } |
| |
| int main() |
| { |
| cin >> n >> m >> S >> T; |
| memset(h, -1, sizeof h); |
| memset(dist, 0x3f, sizeof dist); |
| while (m -- ) |
| { |
| int a, b, c; |
| cin >> a >> b >> c; |
| add(a, b, c); |
| add(b, a, c); |
| } |
| |
| cout << bellman_ford(); |
| |
| return 0; |
| } |
Floyd
原理是动态规划 时间复杂度O(n ^ 3)
| #include <iostream> |
| #include <cstring> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| const int N = 2510; |
| |
| int g[N][N]; |
| int n, m, S, T; |
| |
| |
| int main() |
| { |
| memset(g, 0x3f, sizeof g); |
| scanf("%d%d%d%d", &n, &m, &S, &T); |
| |
| while (m -- ) |
| { |
| int a, b, c; |
| scanf("%d%d%d", &a, &b, &c); |
| g[a][b] = g[b][a] = min(c, g[a][b]); |
| } |
| for (int k = 1; k <= n; k ++ ) |
| for (int i = 1; i <= n; i ++ ) |
| for (int j = 1; j <= n; j ++ ) |
| if (i != j) g[i][j] = min(g[i][j], g[i][k] + g[k][j]); |
| |
| printf("%d", g[S][T]); |
| |
| return 0; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具