迪杰斯特拉算法的具体应用

fill与memset的区别介绍

例一

在这里插入图片描述

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=500;
const int INF=1000000000;
bool isin[maxn]={false};
int G[maxn][maxn];
int path[maxn],rescue[maxn],num[maxn];
int weight[maxn];
int citynum,roadnum,begins,e;void Dijisktra(int a){fill(path,path+maxn,INF);//记录最短距离memset(rescue,0,sizeof(rescue));//记录点权memset(num,0,sizeof(num));//记录最短路径的条数path[a]=0;rescue[a]=weight[a];num[a]=1;for(int i=0;i<citynum;i++){int pi=-1,pv=INF;for(int j=0;j<citynum;j++){//找最短距离的结点if(isin[j]==false&&path[j]<pv){pi=j;pv=path[j];}}if(pi==-1) return;isin[pi]=true;for(int k=0;k<citynum;k++){if(isin[k]==false&&G[pi][k]!=INF){if(G[pi][k]+path[pi]<path[k]){path[k]=G[pi][k]+path[pi];num[k]=num[pi];//更新最短路径数:不相同就覆盖rescue[k]=rescue[pi]+weight[k];}else if(G[pi][k]+path[pi]==path[k]){if(rescue[pi]+weight[k]>rescue[k])rescue[k]=rescue[pi]+weight[k];//存大值num[k]+=num[pi];//最短路径条数之和:相同累加}}}}
}
int main(){int v1,v2;//顶点及边权-距离fill(G[0],G[0]+maxn*maxn,INF);cin>>citynum>>roadnum>>begins>>e;for(int i=0;i<citynum;i++){cin>>weight[i];//记录点权-救援小组数目}for(int j=0;j<roadnum;j++){cin>>v1>>v2>>G[v1][v2];//建立无向图G[v2][v1]=G[v1][v2];}Dijisktra(begins);cout<<num[e]<<" "<<rescue[e];return 0;
}

例二

在这里插入图片描述
在这里插入图片描述

#include <iostream>
using namespace std;
const int maxn=100;
const int INF=1000000000;
bool isin[maxn]={false};
int G[maxn][maxn],expense[maxn][maxn];
int path[maxn],cost[maxn],pre[maxn];
int citynum,roadnum,b,e;void Dijisktra(int a){//求最短路径fill(path,path+maxn,INF);fill(cost,cost+maxn,INF);path[a]=0;cost[a]=0;for(int i=0;i<citynum;i++) pre[i]=i;for(int i=0;i<citynum;i++){int m=-1,mv=INF;for(int j=0;j<citynum;j++){if(isin[j]==false&&path[j]<mv){m=j;mv=path[j];}}if(m==-1) return;isin[m]=true;for(int k=0;k<citynum;k++){if(isin[k]==false&&G[m][k]!=INF){if(G[m][k]+path[m]<path[k]){path[k]=G[m][k]+path[m];cost[k]=expense[m][k]+cost[m];pre[k]=m;}else if(G[m][k]+path[m]==path[k]){if(cost[k]>expense[m][k]+cost[m])cost[k]=expense[m][k]+cost[m];pre[k]=m;}}}}
}
void DFSprint(int now){//打印if(now==b){cout<<now<<" ";return;}DFSprint(pre[now]);cout<<now<<" ";
}
int main(){int v1,v2;fill(G[0],G[0]+maxn*maxn,INF);fill(expense[0],expense[0]+maxn*maxn,INF);cin>>citynum>>roadnum>>b>>e;for(int i=0;i<roadnum;i++){cin>>v1>>v2>>G[v1][v2]>>expense[v1][v2];G[v2][v1]=G[v1][v2];expense[v2][v1]=expense[v1][v2];}Dijisktra(b);DFSprint(e);cout<<path[e]<<" "<<cost[e]<<endl;return 0;
}

拓展

用迪杰斯特拉+DFS求最短路径的方法
关键代码:

const int maxn=100;
const int INF=10000000000;
bool isin[maxn]={false};
int G[maxn][maxn],num;
int path[maxn],w[maxn];
vector<int> pre[maxn];//记录最短路径的前驱:考虑会有多个
vector<int> minPath,temPath;//只记录最优或当前路径void Dijisktra(int a){fill(path,path+maxn,INF);path[a]=0;for(int i=0;i<num;i++){int m=-1,mv=INF;for(int j=0;j<num;j++){if(isin[j]==false&&path[j]<mv){m=j;mv=path[j];}}if(m==-1) return;isin[m]=true;for(int k=0;k<num;k++){if(isin[k]==false&&G[m][k]!=INF){if(G[m][k]+path[m]<path[k]){path[k]=G[m][k]+path[m];//找到更优路径,清空,装最短的pre[k].clear();//m结点加入k结点的前驱列表中,即为pre[k][i]==m;pre[k].push_back(m);}else if(G[m][k]+path[m]==path[k]){
//此时有多条最短路径,即存在多个前驱结点,直接加入即可pre[k].push_back(m);}}}}
}void DFSprint(int now,int begins){int optValue=0;if(now==begins){temPath.push_back(begins);if(value>optValue){//更新最优optValue=value;minPath=temPath;}temPath.pop_back();//弹出第一个return;}temPath.push_back(now);for(int i=0;i<pre[now].size();i++){//遍历当前结点的前驱结点DFSprint(pre[now][i]);//不断递归now结点的前驱列表}temPath.pop_back();//依次弹出第二个.....
}
//计算边权和
int edge=0;
for(int i=temPath.size()-1;i>0;i--){int now=temPath[i],next=temPath[i-1];edge+=G[now][next];//计算边权
}
//计算点权和
int weight=0;
for(int i=temPath.size()-1;i>0;i--){int now=temPath[i];//当前结点下标weight+=w[now];
}

例二:Dijiskatra+DFS

#include <iostream>
#include <vector>
using namespace std;
const int maxn=100;
const int INF=100000000;
bool isin[maxn]={false};
int G[maxn][maxn],expense[maxn][maxn];
int path[maxn],minValue=INF;
vector<int> pre[maxn],temPath,minPath;
int citynum,roadnum,b,e;void Dijisktra(int a){fill(path,path+maxn,INF);path[a]=0;for(int i=0;i<citynum;i++){int m=-1,mv=INF;for(int j=0;j<citynum;j++){if(isin[j]==false&&path[j]<mv){m=j;mv=path[j];}}if(m==-1) return;isin[m]=true;for(int k=0;k<citynum;k++){if(isin[k]==false&&G[m][k]!=INF){if(path[m]+G[m][k]<path[k]){path[k]=path[m]+G[m][k];pre[k].clear();pre[k].push_back(m);}else if(path[m]+G[m][k]==path[k]){pre[k].push_back(m);}}}}
}
void DFSprint(int now){int tempValue=0;if(now==b){temPath.push_back(now);for(int i=temPath.size()-1;i>0;i--){int v1=temPath[i],v2=temPath[i-1];tempValue+=expense[v1][v2];}if(tempValue<minValue){minValue=tempValue;minPath=temPath;}temPath.pop_back();//出队}temPath.push_back(now);for(int i=0;i<pre[now].size();i++){DFSprint(pre[now][i]);}temPath.pop_back();
}
int main(){int v1,v2;fill(G[0],G[0]+maxn*maxn,INF);fill(expense[0],expense[0]+maxn*maxn,INF);cin>>citynum>>roadnum>>b>>e;for(int i=0;i<roadnum;i++){cin>>v1>>v2>>G[v1][v2]>>expense[v1][v2];G[v2][v1]=G[v1][v2];expense[v2][v1]=expense[v1][v2];}Dijisktra(b);DFSprint(e);for(int i=minPath.size()-1;i>=0;i--)cout<<minPath[i]<<" ";cout<<path[e]<<" "<<minValue<<endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/714680.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习数学基础】Hebbian图(Hebbian Graph)

Hebbian图&#xff08;Hebbian Graph&#xff09;是一种基于神经科学原理的网络结构&#xff0c;它受到唐纳德赫布&#xff08;Donald Hebb&#xff09;提出的赫布学习规则&#xff08;Hebb’s rule&#xff09;的启发。赫布学习规则是神经科学中描述神经元之间突触连接如何通过…

模板方法模式 详解 设计模式

模板方法模式 模板方法模式是一种行为型设计模式&#xff0c;它定义了一个算法的骨架&#xff0c;将一些步骤延迟到子类中实现。这种模式允许子类在不改变算法结构的情况下重新定义算法的某些步骤。 结构 抽象类&#xff08;Abstract Class&#xff09;&#xff1a;负责给出一…

JavaWeb老杜视频笔记总结,Servlet-JSP

关于直播 什么时间直播&#xff1f; 晚上8:00到10:00 每周直播几天&#xff1f; 3天&#xff08;周一、周三、周五&#xff09; 本周比较特殊&#xff1a;周四周五周六三天直播&#xff0c;从下周开始就是一三五直播。 直播什么内容&#xff1f; 从JavaWEB开始。&#xff08…

《深入浅出红黑树:一起动手实现自平衡的二叉搜索树》

一、分析 1. 红黑树的性质 红黑树是一种自平衡的二叉搜索树&#xff0c;它具有以下五个性质&#xff1a; &#xff08;1&#xff09;节点是红色或黑色。 &#xff08;2&#xff09;根节点是黑色。 &#xff08;3&#xff09;所有叶子节点&#xff08;NIL节点&#xff09;是…

探索数据宇宙:深入解析大数据分析与管理技术

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…

第六课:NIO简介

一、传统BIO的缺点 BIO属于同步阻塞行IO,在服务器的实现模型为&#xff0c;每一个连接都要对应一个线程。当客户端有连接请求的时候&#xff0c;服务器端需要启动一个新的线程与之对应处理&#xff0c;这个模型有很多缺陷。当客户端不做出进一步IO请求的时候&#xff0c;服务器…

《Spring Security 简易速速上手小册》第4章 授权与角色管理(2024 最新版)

文章目录 4.1 理解授权4.1.1 基础知识详解授权的核心授权策略方法级安全动态权限检查 4.1.2 主要案例&#xff1a;基于角色的页面访问控制案例 Demo 4.1.3 拓展案例 1&#xff1a;自定义投票策略案例 Demo测试自定义投票策略 4.1.4 拓展案例 2&#xff1a;使用方法级安全进行细…

【flutter】加载指示器(loading indicator)阻止用户在某个操作执行期间操作页面

在Flutter中&#xff0c;通过显示一个加载指示器&#xff08;loading indicator&#xff09;来阻止用户在某个操作执行期间操作页面。以下是一个简单的示例代码&#xff0c;演示了按钮被点击后执行某操作&#xff0c;在操作完成前显示加载指示器&#xff0c;阻止用户操作页面&a…

c语言数据结构(5)——栈

欢迎来到博主的专栏——C语言数据结构 博主id&#xff1a;代码小豪 文章目录 栈栈的顺序存储结构栈的插入空栈的初始化栈的删除判断空栈读取栈顶元素数据 实现顺序栈的所有代码栈的链式存储结构链式栈的初始化链式栈的入栈操作链式栈的出栈操作 实现链式栈的所有代码 栈 栈是…

学习网络编程No.11【传输层协议之UDP】

引言&#xff1a; 北京时间&#xff1a;2023/11/20/9:17&#xff0c;昨天成功更文&#xff0c;上周实现了更文两篇&#xff0c;所以这周再接再厉。当然做题任在继续&#xff0c;而目前做题给我的感觉以套路和技巧偏多&#xff0c;还是那句话很多东西不经历你就是不懂&#xff…

测试人员如何向开发人员准确清晰地描述问题?

测试人员向开发人员准确清晰地描述问题可以采取以下方法&#xff1a; 提供详细的背景和上下文信息&#xff1a;描述问题发生的环境、前提条件和操作步骤&#xff0c;让开发人员能够了解问题出现的场景。明确问题的症状和表现&#xff1a;清楚地说明问题的具体表现&#xff0c;…

【Python】2. 基础语法

常量和表达式 我们可以把 Python 当成一个计算器, 来进行一些算术运算. 注意: print 是一个 Python 内置的 函数, 这个稍后详细介绍. 可以使用 - * / ( ) 等运算符进行算术运算. 先算乘除, 后算加减. 运算符和数字之间, 可以没有空格, 也可以有多个空格. 但是一般习惯上写一…

LDR6328芯片:智能家居时代的小家电充电革新者

在当今的智能家居时代&#xff0c;小家电的供电方式正变得越来越智能化和高效化。 利用PD&#xff08;Power Delivery&#xff09;芯片进行诱骗取电&#xff0c;为后端小家电提供稳定电压的技术&#xff0c;正逐渐成为行业的新宠。在这一领域&#xff0c;LDR6328芯片以其出色的…

Qt下使用modbus-c库实现PLC线圈/保持寄存器的读写

系列文章目录 提示&#xff1a;这里是该系列文章的所有文章的目录 第一章&#xff1a;Qt下使用ModbusTcp通信协议进行PLC线圈/保持寄存器的读写&#xff08;32位有符号数&#xff09; 第二章&#xff1a;Qt下使用modbus-c库实现PLC线圈/保持寄存器的读写 文章目录 系列文章目录…

前端Vue3项目如何打包成Docker镜像运行

将前端Vue3项目打包成Docker镜像并运行包括几个主要步骤&#xff1a;项目打包、编写Dockerfile、构建镜像和运行容器。下面是一个基本的流程&#xff1a; 1. 项目打包 首先&#xff0c;确保你的Vue3项目可以正常运行和打包。在项目根目录下执行以下命令来打包你的Vue3项目&am…

nest.js使用nest-winston日志一

nest-winston文档 nest-winston - npm 参考&#xff1a;nestjs中winston日志模块使用 - 浮的blog - SegmentFault 思否 安装 cnpm install --save nest-winston winstoncnpm install winston-daily-rotate-file 在main.ts中 import { NestFactory } from nestjs/core; im…

【5G 接口协议】GTP-U协议介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

mysql学习

查看glibc版本 ldd --version --mysql启动失败,尝试启动 1 查看错误日志,端口被占用,参数名写错,有不支持的参数 2 通过mysqld启动 mysqld --default-filemy.cnf & 3 mysqld --no-defaults --basedir/user/local/mysql --datadir/data/mysql/3306/data/ --usermysql 4 str…

深入理解 Nginx 的负载均衡与反向代理

深入理解 Nginx 的负载均衡与反向代理 Nginx 是一个高性能的 HTTP 和反向代理服务器&#xff0c;也是一个 IMAP/POP3/SMTP 代理服务器。由于其出色的性能和灵活性&#xff0c;Nginx 已成为现代 web 架构中的重要组成部分&#xff0c;尤其是在处理高并发连接和大规模流量时。在…

找到数组的中间位置-1991-[简单]

力扣 关键点 从题目中总结出公式 sum * 2 nums[i] total从左往右开始尝试&#xff0c;寻找 i 位置满足上面的公式&#xff0c;为什么从左开始&#xff0c;因为题目要求找到最左边的一个用前缀和的概念来解&#xff0c;从左往右尝试i位置的左边所有数之和&#xff0c;右边所有…