要发财的小熊猫很靠谱 level
获赞
2
粉丝
5
关注
0
看过 TA
80
门头沟学院
2025
C++
IP属地:江西
暂未填写个人简介
私信
关注
2024-12-30 17:16
门头沟学院 C++
Bellman_ford 队列优化算法:Bellman_ford 算法每次松弛 都是对所有边进行松弛。但真正有效的松弛,是基于已经计算过的节点在做的松弛;队列优化算法只对 上一次松弛的时候更新过的节点作为出发节点所连接的边 进行松弛,用队列来记录上次松弛的时候更新过的节点。已经在队列里的元素不用重复添加,而从队列里取出的时候,要取消标记。这是因为每个要加入队列的节点,都是一次松弛后得到了更小距离的节点,以它作为出发节点的边也可以获得更小距离。所以如果此时该节点已经再队列里,没有必要再加一次,因为它还没出队更新,一旦出队就会更新好当前情况下的最小距离,但是从队列取出时要取消标记,因为可能该节点的最小距离还会得到更新(找到其它节点到它的路最短),那么以它为出发节点的边也要进行更新!bellman_ford判断负权回路:在有负权回路的情况下,一直都会有更短的最短路,所以松弛第n次,minDist数组也会发生改变所以判断是否有负权回路,就是在松弛n-1次的基础上再多松弛一次,看minDist数组是否发生变化bellman_ford单源有限最短路:计算在最多经过 k 个城市的条件下,从城市 src 到城市 dst 的最低运输成本,最多经过 k 个城市, 那么是 k + 1条边相连的节点,所以本题就是求:起点最多经过k + 1 条边到达终点的最短距离。根据之前对所有边松弛一次,相当于计算 起点到达 与起点一条边相连的节点 的最短距离得知:对所有边松弛 k + 1次,就是求 起点到达 与起点k + 1条边相连的节点的 最短距离。在有负权回路的情况下,还需要注意使用上次的minDist数组
0 点赞 评论 收藏
分享
2024-12-27 14:40
已编辑
门头沟学院 C++
dijkstra(堆优化版):从边的数量出发,采用邻接表存储图:vector<list<pair<int,int>>> grid(n + 1);构建小顶堆来直接选最近结点(不需要循环),优先级队列中存放pair<结点编号,结点到起点的距离>,使用vector<pair<int, int>>作为底层容器,并通过mycomparison类来比较元素;priority_queue<pair<int,int>, vector<pair<int,int>>, mycomparison> pq;时间复杂度:O(ElogE) E 为边的数量Bellman_ford 算法:求带负权值的单向最短路,dijkstra算法只能求权值为非负数的最短路问题。思路:对所有边松弛 n-1 次,然后得出得到终点的最短路径。对所有边松弛一次,相当于计算 起点到达 与起点一条边相连的节点 的最短距离,松弛就是一次去获取到该结点的最短路径的尝试,因为给出的边规定了哪个结点到哪个结点有路,这说明某次的松弛操作不一定能真正实行,可能起点到某条边的出发结点还未找到最短路,所以要松弛n-1次,才能最终得到起点到终点的最短路。// 松弛操作 // minDist[from] != INT_MAX 防止从未计算过的节点出发if (minDist[from] != INT_MAX && minDist[to] > minDist[from] + price) {       minDist[to] = minDist[from] + price;  }时间复杂度: O(N * E) , N为节点数量,E为图中边的数量
0 点赞 评论 收藏
分享
2024-12-26 22:13
门头沟学院 C++
dijkstra算法求最短路径:与prim算法很相似,步骤几乎一直,但prim求的是所有结点都连通起来的最小值,而dijkstra求的是有向图的起点到终点的最短路径,不需要连通所有结点,所以求结果的过程稍有不同。prim算法中的minDist数组求的是当前结点(还未加入生成树的结点)到现有生成树的最近距离,这个距离会因为每次生成树新节点的加入进行更新),输出结果也是对minDist数组进行累加;而dijkstra算法中minDist数组求的是当前结点到起点(结点1)的最小距离,输出结果就是终点(结点n)到起点的最小距离minDist[n]。//dijkstra三部曲://1、选起点到哪个节点近且该节点未被访问过//2、对该最近节点标记为已访问//3、更新还未访问节点到起点的距离(即更新minDist数组)拓扑排序:给出一个有向图(具有复杂的依赖关系),把这个有向图转成线性的排序就叫拓扑排序,如大学排课,文件处理等。同时要检测有向图中是否有环,有环则不能得到线性排序,所以拓扑排序也是图论中判断有向无环图的常用方法。思路:1、找到入度为0(出发结点)的结点,加入结果集2、将该结点从图中移除3、循环上面两步,直到图中所有结点都被移除用vector记录每个文件的入度,入度为0的结点存放在queue里,依赖关系放在unordered_map<int, vector<int>>里当构造依赖关系时就将依赖别人的文件入度+1,最后遍历将入度为0的结点加入队列,然后依次将队列里的结点弹出,此时将该节点从图中移除意味着依赖它的结点的入度要-1,并判断是否入度为0,是的话加入队列。判断有 有向环 的存在:如果找不到入度为0的节点了且此时结果集中的元素个数不等于图中结点个数,就说明有环
0 点赞 评论 收藏
分享
2024-12-23 16:57
门头沟学院 C++
并查集功能:1、寻找根节点,函数:find(int u),判断这个节点的祖先节点是哪个2、将两个节点接入到同一个集合,函数:join(int u, int v),将两个节点连在同一个根节点上3、判断两个节点是否在同一个集合,函数:isSame(int u, int v),就是判断两个节点是不是同一个根节点代码模板:int n = 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好vector<int> father = vector<int> (n, 0); // C++里的一种数组结构// 并查集初始化void init() {    for (int i = 0; i < n; ++i) {        father[i] = i;    }}// 并查集里寻根的过程int find(int u) {    return u == father[u] ? u : father[u] = find(father[u]); // 路径压缩}// 判断 u 和 v是否找到同一个根bool isSame(int u, int v) {    u = find(u);    v = find(v);    return u == v;}// 将v->u 这条边加入并查集void join(int u, int v) {    u = find(u); // 寻找u的根    v = find(v); // 寻找v的根    // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回    if (u == v) return ;     father[v] = u;}今天得开始写毕业论文了,先把框架整理好!最近学了workflow作为客户端和服务端(http服务器和静态资源管理服务器),开始学wfrest包装的workflow作为HTTP服务器,主要是减少了url提取查询参数,方法,路径这些复杂的字符串切割操作,简化了workflow服务端的使用。
0 点赞 评论 收藏
分享

创作者周榜

更多
关注他的用户也关注了:
牛客网
牛客企业服务