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

news2024/9/23 15:31:37

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.coloradmin.cn/o/1483851.html

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

相关文章

Linux内存地址空间

目录 一、虚拟地址空间 1.虚拟地址空间的定义 2.虚拟地址空间的布局 二、内存壁垒 1.内存壁垒的定义​编辑 2.段错误 三、内存映射的建立与解除 &#xff08;1&#xff09;mmap &#xff08;2&#xff09;munmap &#xff08;3&#xff09;堆内存的分配和释放 1.sbrk …

一文掌握大模型提示词技巧:从战略到战术

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

【c++】构造函数(下)——初始化列表

Hello,everybody!构造函数的内容比较多&#xff0c;语法还有些复杂。我分成了两篇文章进行讲解&#xff0c;大家在看过构造函数(上)后再来看这篇文章更容易理解哟&#xff01; 1.初始化列表的格式 类似这种格式&#xff0c;在初始化列表中第一行用冒号开头&#xff0c;剩下的用…

无线通信中AM,FM,PM与之相关的调制类型说明,例如F2D,F1W,F3E等

常见例子&#xff1a; 广播 A3E或A3E G 普通幅度调制用于低频和中频AM广播F8E&#xff0c;F8E H 用于VHF上的无线电传输的FM广播&#xff0c;以及模拟电视传输的音频分量。 由于通常使用用于立体声和RDS的导频音&#xff08;子载波&#xff09;&#xff0c;使用指示符“8”…

C++ 原子变量

概述 C中原子变量&#xff08;atomic&#xff09;是一种多线程编程同步机制&#xff0c;它能够确保对共享变量的操作在执行时不会被其他线程的操作干扰&#xff0c;atomic是提供一种生成原子操作数的一种机制&#xff0c;避免竞态条件(race condition)和死锁(deadlock)等问题。…

生成式AI与仿真

仿真模型是物理对象、系统或过程的虚拟表示&#xff0c;可预测其在不同场景中的行为和性能。 如今&#xff0c;仿真模型广泛应用于各行各业&#xff0c;以优化流程、为决策提供信息并创建数字孪生。 几十年来&#xff0c;仿真模型一直被用来对复杂的系统和过程进行建模。 这些…

Python 编辑工具 Jupyter notebook

Jupyter notebook Jupyter Notebook是基于网页的用于交互计算的应用程序。其可被应用于全过程计算&#xff1a;开发、文档编写、运行代码和展示结果。——Jupyter Notebook官方介绍 官网&#xff1a;Project Jupyter | Home Jupyter Notebook 是一个开源的交互式计算环境&#…

selenium爬虫

方法选择和安装包 在动态网页并且登陆过程中不需要进行过于复杂的密码验证的时候使用selenium会非常的方便 安装准备过程也相对简单&#xff1a; 下载对应版本的chromedriver并且通过如下代码找到路径下载到python所在的目录&#xff1a; import sysprint(sys.executable) …

技巧 文本编辑器 B列每一行数据换行合并到A列中

一. 需求背景 ⏹A列是我们制作的日文版歌词&#xff0c;B列是中文版译文歌词 现在想让B列的每一行歌词&#xff0c;按下图箭头所示插入到A列的每一行后面 二. 通过文本编辑器的替换功能解决 将Excel中的A和B列的数据复制粘贴到文本编辑器中Excel中的列和列之前是通过Tab来分隔…

代码随想录算法训练营29期|day64 任务以及具体安排

第十章 单调栈part03 有了之前单调栈的铺垫&#xff0c;这道题目就不难了。 84.柱状图中最大的矩形class Solution {int largestRectangleArea(int[] heights) {Stack<Integer> st new Stack<Integer>();// 数组扩容&#xff0c;在头和尾各加入一个元素int [] ne…

Aigtek高精度电流源仪器设计规范

高精度电流源仪器是一种用于产生和测量精确电流的设备&#xff0c;广泛应用于电子、通信、自动控制等领域。为了确保仪器的性能和可靠性&#xff0c;设计过程中需要遵循一些规范。 电流源仪器的设计要注重稳定性。稳定性是保证仪器输出电流精度的关键因素。设计过程中应选择高精…

数据恢复软件哪个好?推荐10款好用的数据恢复软件

在数字化时代&#xff0c;数据的安全性和可恢复性变得至关重要。由于各种原因&#xff0c;如设备故障、误删、病毒攻击等&#xff0c;我们可能会面临数据丢失的风险。为了应对这种情况&#xff0c;市场上涌现出许多数据恢复软件。但是哪款软件更适合你的需求呢&#xff1f;下面…

Python 教学平台,支持“多班教学”的课程授课方式|ModelWhale 版本更新

龙行龘龘、前程朤朤&#xff0c;ModelWhale 新一轮的版本更新&#xff0c;期待为大家带来更优质的使用体验。 本次更新中&#xff0c;ModelWhale 主要进行了以下功能迭代&#xff1a; 新增 课程&#xff08;包括课件、作业、算力&#xff09;按班级管理&#xff08;团队版✓ …

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的行人车辆检测与计数(Python+PySide6界面+训练代码)

摘要&#xff1a;开发行人车辆检测与计数系统对于提升城市交通管理和监控系统的效率至关重要。本篇博客详细介绍了如何利用深度学习构建一个行人车辆检测与计数系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并结合了YOLOv7、YOLOv6、YOLOv5…

java找工作之JavaWeb(一)

JavaWeb 一个web应用有多部份组成&#xff08;静态web&#xff0c;动态web&#xff09; html&#xff0c;css&#xff0c;jsjsp&#xff0c;servletjava程序jar包配置文件(Properties) web应用程序编写完毕后&#xff0c;若想提供给外界访问&#xff0c;需要一个服务器来统一…

值得一试的五大AI编程助手

AI编程助手已成为开发过程中不可缺少的一部分&#xff0c;因为它们可以协助代码生成、理解、项目搜索以及使用提示或代码执行各种任务。甚至像谷歌Colab和Deepnote这样的云IDE平台也提供AI辅助编程&#xff0c;可以帮助您生成代码并解决问题。 本文将介绍5款值得一试的AI编程助…

效率真高!众安保险数据分析岗(实习)面试通过了,分享一下面试经验!

最近&#xff0c;我们社群组织了一场技术&面试讨论会&#xff0c;邀请了一些互联网大厂同学、参加社招和校招面试的同学&#xff0c;针对新手如何入门数据分析、机器学习算法、该如何备战、面试常考点分享等热门话题进行了深入的讨论。 基于社群的讨论&#xff0c;今天我整…

ApplicationContext容器

ApplicationContext容器 1.概述 ApplicationContext接口代表了一个Spring容器,它主要负责实例化、配置和组装bean。ApplicationContext接口间接继承了BeanFactory接口,相较于BeanFactory一些基本的容器功能,ApplicationContext接口是在BeanFactory接口基础上进行了扩展,增…

Snagit 2024:让你的屏幕活动瞬间变得生动有力 mac/win版

Snagit 2024 屏幕录制与截图软件是一款功能强大的工具&#xff0c;专为现代用户设计&#xff0c;以满足他们在工作、学习和娱乐中对屏幕内容捕捉和分享的需求。这款软件结合了屏幕录制和截图功能&#xff0c;为用户提供了一种高效、便捷的方式来捕捉屏幕上的精彩瞬间。 Snagit…