图论算法 待补充
2022/2/6 17:16:57
本文主要是介绍图论算法 待补充,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
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; }
这篇关于图论算法 待补充的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南