1. 贝尔福特曼
#include<iostream> using namespace std; #include<cstring> #include<cstdio> struct edge { int s, e, v; //起点,终点,边权 }; edge edg[200005]; //存储两次 int n, m, s, ans[100005], cnt; void add_edge(int a, int b, int c) { edg[cnt].s = a; edg[cnt].e = b; edg[cnt].v = c; cnt++; } int main() { memset(ans, 0x3f, sizeof(ans)); scanf_s("%d%d%d", &n, &m, &s); for (int i = 0; i < m; i++) { int a, b, c; scanf_s("%d%d%d", &a, &b, &c); add_edge(a, b, c); add_edge(b, a, c); } ans[s] = 0; for (int i = 0; i < n; i++) { int f = 0; for (int j = 0; j < cnt; j++) { int e = edg[j].e, s = edg[j].s, v = edg[j].v; if (ans[e] > ans[s] + v) { ans[e] = ans[s] + v; f = 1; } } if (!f) break; } for (int i = 1; i <= n; i++) { if (ans[i] == 0x3f3f3f3f) puts("-1"); else printf("%d\n", ans[i]); } return 0; }
2. 链式前向星+迪杰斯特拉
#include<iostream> #include<queue> #include<cstring> #include<cstdio> using namespace std; struct edge { int e, v, nnext; //终点,权重,下一个点的下标 }; struct node { int now, dis; bool operator<(const node& b)const { return this->dis > b.dis; } }; edge edg[1000005]; int n, m, s, ans[100005], head[100005], cnt; void add_edge(int a, int b, int c) { edg[cnt].e = b; edg[cnt].v = c; edg[cnt].nnext = head[a]; head[a] = cnt++; } int main() { memset(head, -1, sizeof(head)); memset(ans, 0x3f, sizeof(ans)); scanf_s("%d%d%d", &n, &m, &s); for (int i = 0; i < m; i++) { int a, b, c; scanf_s("%d%d%d", &a, &b, &c); add_edge(a, b, c); add_edge(b, a, c); } priority_queue<node>que; que.push(node{ s,0 }); ans[s] = 0; while (!que.empty()) { node temp = que.top(); que.pop(); if (ans[temp.now] < temp.dis) { continue; } for (int i = head[temp.now]; i != -1; i = edg[i].nnext) { int e = edg[i].e, v = edg[i].v; if (ans[e] > ans[temp.now] + v) { ans[e] = ans[temp.now] + v; que.push(node{ e,ans[e] }); } } } for (int i = 1; i <= n; i++) { if (ans[i] == 0x3f3f3f3f) puts("-1"); else printf("%d\n", ans[i]); } return 0; }
3. 链式前向星+基于队列优化的贝尔福特曼
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; struct edge { int e, v, nnext; }; edge edg[200005]; //存储两次 int n, m, s, ans[100005], head[100005], mark[100005], cnt; void add_edge(int a, int b, int c) { edg[cnt].e = b; edg[cnt].v = c; edg[cnt].nnext = head[a]; head[a] = cnt++; } int main() { memset(ans, 0x3f, sizeof(ans)); memset(head, -1, sizeof(head)); scanf_s("%d%d%d", &n, &m, &s); for (int i = 1; i <= m; i++) { int a, b, c; scanf_s("%d%d%d", &a, &b, &c); add_edge(a, b, c); add_edge(b, a, c); } queue<int> que; ans[s] = 0; que.push(s); mark[s] = 1; while (!que.empty()) { int temp = que.front(); que.pop(); mark[temp] = 0; for (int i = head[temp]; i != -1; i = edg[i].nnext) { int e = edg[i].e, v = edg[i].v; if (ans[e] > ans[temp] + v) { ans[e] = ans[temp] + v; if (mark[e] == 0) { que.push(e); mark[e] = 1; } } } } for (int i = 1; i <= n; i++) { if (ans[i] == 0x3f3f3f3f) puts("-1"); else printf("%d\n", ans[i]); } return 0; }
4. 邻接表+迪杰斯特拉
#include<iostream> #include<vector> #include<queue> #include<cstring> #include<cstdio> using namespace std; int n, m, s, ans[100005]; struct node { int now, dis; //小顶堆需要重载大于号 bool operator<(const node& b)const { return this->dis > b.dis; } }; struct edge { int e, v; //e终点,v权重 }; int main() { memset(ans, 0x3f, sizeof(ans)); scanf_s("%d%d%d", &n, &m, &s); vector<vector<edge> >edg(n + 5, vector<edge>()); for (int i = 0; i < m; i++) { int a, b, c; scanf_s("%d%d%d", &a, &b, &c); edg[a].push_back(edge{ b,c }); edg[b].push_back(edge{ a,c }); } priority_queue<node>que; que.push(node{ s,0 }); ans[s] = 0; while (!que.empty()) { node temp = que.top(); que.pop(); if (ans[temp.now] < temp.dis) { continue; } for (int i = 0; i < edg[temp.now].size(); i++) { int e = edg[temp.now][i].e, v = edg[temp.now][i].v; if (ans[e] > temp.dis + v) { ans[e] = temp.dis + v; que.push(node{ e,ans[e] }); } } } for (int i = 1; i <= n; i++) { if (ans[i] == 0x3f3f3f3f) puts("-1"); else printf("%d\n", ans[i]); } return 0; }
5. 邻接矩阵+弗洛伊德
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int ans[1005][1005], n, m, s; int main() { memset(ans, 0x3F, sizeof(ans)); scanf_s("%d%d%d", &n, &m, &s); for (int i = 1; i <= m; i++) { int a, b, c; scanf_s("%d%d%d", &a, &b, &c); if (ans[a][b] > c) { ans[a][b] = c; ans[b][a] = c; } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { for (int k = 1; k <= n; k++) { ans[j][k] = min(ans[j][k], ans[j][i] + ans[i][k]); } } } for (int i = 1; i <= n; i++) { ans[i][i] = 0; if (ans[s][i] == 0x3F3F3F3F) { puts("-1"); } else { printf("%d\n", ans[s][i]); } } return 0; }