欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 文化 > 算法训练营第七十六天(最后一天、完结撒花) | Bellmanford之单源有限最短路、Floyd算法、A*算法

算法训练营第七十六天(最后一天、完结撒花) | Bellmanford之单源有限最短路、Floyd算法、A*算法

2024/10/23 23:31:35 来源:https://blog.csdn.net/qq_63149342/article/details/140163219  浏览:    关键词:算法训练营第七十六天(最后一天、完结撒花) | Bellmanford之单源有限最短路、Floyd算法、A*算法

算法训练营最后一天 | Bellmanford之单源有限最短路、Floyd算法、A*算法

Bellmanford之单源有限最短路

题目连接:
https://kamacoder.com/problempage.php?pid=1154

在之前的基础上松弛k+1次而不是n+1次即可

#include <iostream>
#include <vector>
#include <list>
#include <climits>
using namespace std;int main() {int src, dst,k ,p1, p2, val ,m , n;cin >> n >> m;vector<vector<int>> grid;for(int i = 0; i < m; i++){cin >> p1 >> p2 >> val;grid.push_back({p1, p2, val});}cin >> src >> dst >> k;vector<int> minDist(n + 1 , INT_MAX);minDist[src] = 0;vector<int> minDist_copy(n + 1); // 用来记录上一次遍历的结果for (int i = 1; i <= k + 1; i++) {minDist_copy = minDist; // 获取上一次计算的结果for (vector<int> &side : grid) {int from = side[0];int to = side[1];int price = side[2];// 注意使用 minDist_copy 来计算 minDist if (minDist_copy[from] != INT_MAX && minDist[to] > minDist_copy[from] + price) {  minDist[to] = minDist_copy[from] + price;}}}if (minDist[dst] == INT_MAX) cout << "unreachable" << endl; // 不能到达终点else cout << minDist[dst] << endl; // 到达终点最短路径}

Floyd算法

题目链接:
https://kamacoder.com/problempage.php?pid=1155

#include <iostream>
#include <vector>
#include <list>
using namespace std;int main() {int n, m, p1, p2, val;cin >> n >> m;vector<vector<vector<int>>> grid(n + 1, vector<vector<int>>(n + 1, vector<int>(n + 1, 10005)));  // 因为边的最大距离是10^4for(int i = 0; i < m; i++){cin >> p1 >> p2 >> val;grid[p1][p2][0] = val;grid[p2][p1][0] = val; // 注意这里是双向图}// 开始 floydfor (int k = 1; k <= n; k++) {for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {grid[i][j][k] = min(grid[i][j][k-1], grid[i][k][k-1] + grid[k][j][k-1]);}}}// 输出结果int z, start, end;cin >> z;while (z--) {cin >> start >> end;if (grid[start][end][n] == 10005) cout << -1 << endl;else cout << grid[start][end][n] << endl;}
}

A*算法

题目链接:
https://kamacoder.com/problempage.php?pid=1203

#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
int moves[1001][1001];
int dir[8][2]={-2,-1,-2,1,-1,2,1,2,2,1,2,-1,1,-2,-1,-2};
int b1, b2;
// F = G + H
// G = 从起点到该节点路径消耗
// H = 该节点到终点的预估消耗struct Knight{int x,y;int g,h,f;bool operator < (const Knight & k) const{  // 重载运算符, 从小到大排序return k.f < f;}
};priority_queue<Knight> que;int Heuristic(const Knight& k) { // 欧拉距离return (k.x - b1) * (k.x - b1) + (k.y - b2) * (k.y - b2); // 统一不开根号,这样可以提高精度
}
void astar(const Knight& k)
{Knight cur, next;que.push(k);while(!que.empty()){cur=que.top(); que.pop();if(cur.x == b1 && cur.y == b2)break;for(int i = 0; i < 8; i++){next.x = cur.x + dir[i][0];next.y = cur.y + dir[i][1];if(next.x < 1 || next.x > 1000 || next.y < 1 || next.y > 1000)continue;if(!moves[next.x][next.y]){moves[next.x][next.y] = moves[cur.x][cur.y] + 1;// 开始计算Fnext.g = cur.g + 5; // 统一不开根号,这样可以提高精度,马走日,1 * 1 + 2 * 2 = 5next.h = Heuristic(next);next.f = next.g + next.h;que.push(next);}}}
}int main()
{int n, a1, a2;cin >> n;while (n--) {cin >> a1 >> a2 >> b1 >> b2;memset(moves,0,sizeof(moves));Knight start;start.x = a1;start.y = a2;start.g = 0;start.h = Heuristic(start);start.f = start.g + start.h;astar(start);while(!que.empty()) que.pop(); // 队列清空cout << moves[b1][b2] << endl;}return 0;
}

训练营总结

陆陆续续刷了两个多月题目。基础得到了巩固,不会的东西也有了基本的了解,基本的知识体系是构建起来了。

之后还是要自己花时间去巩固后面图论和动规部分题目,很多都是看题解记住了思路之后去实现,并没有自己真的理解并且灵活运用,这样在面对各种各样变化莫测的笔试题的时候真的会吃大亏。

这次训练营,是我为了弥补大一上学期因为参加社团活动落下的功课而参加的。也确实弥补了当时因为自己能力不足、没有坚持下去而错失被选为正式成员的机会,而产生的很大的遗憾。

我知道自己很多方面做得还不够好,点赞量几乎没有,收藏量时有时无,评论量都是水出来的。博客链接放到简历里几乎也都挂了,而且期间参加的面试,做的项目都不怎么样。

难道我真的只有做一点小事做到很简单的水准,没法儿再提升了的潜力?我希望不是这样,也希望接下来的时间里,我能拿出实际行动推翻事实对我的否定,当然这否定也必然是我自己造成的。

不管怎么说,这才只是开始,后面的路会更难走,我也对即将到来的更大的磨难和挑战充满了期待。

当然,我还很无知,简直无知到我自己都无法忍受的地步,每天都想尽力往前再进一步,然而只能一步一步慢慢前进

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com