首页 > 编程语言 >迪杰斯特拉算法(Dijkstra算法)

迪杰斯特拉算法(Dijkstra算法)

时间:2023-03-29 23:14:10浏览次数:44  
标签:10 结点 int 路径 迪杰 Dijkstra 算法

洛谷P1821 [USACO07FEB] Cow Party S

https://www.luogu.com.cn/problem/P1821

一、递归

/*
B1631 [Usaco2007 Feb]Cow Party
====关键词===================================================
思路:迪杰斯特拉(dijkstra)
1.从地图中,找从x到所有结点的距离(牛返回的路径)
2.从反向地图中,找从x到所有结点的距离(牛出发的路径)
3.将两距离数组相加,遍历(除了结点x),筛选出最大的值,返回
别人的题解
https://blog.csdn.net/weixin_43845956/article/details/111177171
====关键词===================================================
====题目===================================================
题目描述
寒假到了,n 头牛都要去参加一场在编号为 x 的牛的农场举行的派对,农场之间有 m 条有向路,每条路都有一定的长度。
每头牛参加完派对后都必须回家,无论是去参加派对还是回家,每头牛都会选择最短路径,求这 n 头牛的最短路径(一个来回)中最长的一条路径长度。
输入格式
第一行有三个整数,分别表示牛的数量 n,道路数 m 和派对农场编号 x。
接下来 m 行,每行三个整数 u, v, w 表示存在一条由 u 通向 v 的长度为 w 的道路。
对于全部的测试点,保证1≤x≤n≤10^3,1≤m≤10^5 ,1≤u,v≤n,1≤w≤10^2,保证从任何一个结点出发都能到达 x 号结点,且从 x 出发可以到达其他所有节点。
输出格式
输出一行一个整数表示答案。
样例输入
4 8 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3
样例输出
10
提示
样例说明:
共有 4 只奶牛参加聚会,有 8 条路,聚会位于第 2 个农场.
第 4 只奶牛可以直接到聚会所在地 (花费 3 时间), 然后返程路线经过第 1 和第 3 个农场 (花费 7 时间), 总共 10 时间.
====题目===================================================
*/
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#define INF 99999999
using namespace std;

const int N = 1001; //牛数量上限(下标从1开始,多分配一些空间)
int mmap1[N][N];    //地图,0表示无路径,非0表示有路径
int mmap2[N][N];    //反向地图(弧的指向相反),0表示无路径,非0表示有路径
int n, m, x;        //牛数量,道路数,农场编号
int ansdis[N];      //结果
int ans;            //最终结果
//迪杰特斯拉算法求最短路,需要的数组
int pre[N];     //结点的前面结点(可获得路径)
int dis1[N];    //求解出的距离,牛返回
int dis2[N];    //求解出的距离,牛出发
int dis[N];     //存放迪杰特斯拉算法的结果
bool okNode[N]; //结点是否确定了最小距离
void showDisVisited();
void showmmap(int mmap[][N]);
/*
求从起点s到其余点的距离
*/
bool allokNode()
{ //判断结点是否全部被使用
    for (int i = 1; i <= n; i++)
    {
        if (okNode[i] == false)
            return false;
    }
    return true;
}
void updateNode(int mmap[][N], int s)
{ //找临近结点,并更新表
    if (allokNode())
        return; //结点全部被使用,终止递归map

    //更新dis
    for (int j = 1; j <= n; j++)
    { //找s指向的结点
        if (mmap[s][j] != 0)
        { //有指向的结点j
            if (!okNode[j])
            { //结点j未确定最短路
                if (dis[s] + mmap[s][j] < dis[j])
                { //新路径比老路径距离短,升级
                    dis[j] = dis[s] + mmap[s][j];
                    pre[j] = s;
                }
            }
        }
    }
    //寻找并收录权值最小的结点
    int minDis = INF, minNode = 0; //距离最小值,结点下标
    for (int j = 1; j <= n; j++)
    {
        if (okNode[j])
            continue;
        if (dis[j] < minDis)
        { //更新最小权值的结点
            minDis = dis[j];
            minNode = j;
        }
    }
    // showDisVisited();//调试
    pre[minNode] = s;
    okNode[minNode] = true;
    // cout << "okNode[" << minNode << "] = " << okNode[minNode] << endl;//调试

    //更新收录结点的临近结点
    updateNode(mmap, minNode);
}
/*
mmap:地图矩阵
dis:输出的距离矩阵
s:起点下标
*/
void dijkstra(int mmap[][N], int s)
{ //迪杰特斯拉算法求最短路
    //初始化
    memset(pre, -1, sizeof(pre));
    for (int i = 1; i <= n; i++)
    {
        dis[i] = INF;
    }
    // memset(dis, INF, sizeof(dis));
    memset(okNode, false, sizeof(okNode));
    //算法
    //第一个结点,直接插入
    dis[s] = 0;  //结点到自己的距离是0
    pre[s] = -1; //第一个结点没有前驱
    okNode[s] = true;
    // cout << "okNode[" << s << "] = " << okNode[s] << endl; //调试
    //后面的结点,调用函数
    // showDisVisited();//调试
    updateNode(mmap, s);
    //返回求解出的数组
}

int main()
{
    //接收数据,数据初始化
    scanf("%d%d%d", &n, &m, &x);
    for (int i = 1; i <= m; i++)
    {
        int s, e, dis;
        scanf("%d%d%d", &s, &e, &dis);
        mmap1[s][e] = dis; //原始地图
        mmap2[e][s] = dis; //反向地图
    }
    // showmmap(mmap1);
    // showmmap(mmap2);
    //题解
    // showDisVisited();//调试
    dijkstra(mmap1, x);
    memcpy(dis1, dis, sizeof(dis)); //返回的路
    // showDisVisited();               //调试
    dijkstra(mmap2, x);
    memcpy(dis2, dis, sizeof(dis)); //出发的路
    // showDisVisited();               //调试
    for (int i = 1; i <= n; i++)
    {
        if (i != x)
            ans = max(ans, dis1[i] + dis2[i]);
    }
    //输出结果
    printf("%d\n", ans);
    return 0;
}

void showmmap(int mmap[][N])
{ //显示地图矩阵
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            if (mmap[i][j] != INF)
                printf("%d ", mmap[i][j]);
            else
                printf("INF ");
        }
        puts("");
    }
}
void showDisVisited()
{ //显示结点距离信息
    printf("下标\t");
    for (int i = 1; i <= n; i++)
    {
        printf("%5d ", i);
    }
    puts("");
    printf("okNode[]");
    for (int i = 1; i <= n; i++)
    {
        printf("%5d ", okNode[i]);
    }
    puts("");
    printf("dis[]\t");
    for (int i = 1; i <= n; i++)
    {
        printf("%5d ", dis[i]);
    }
    puts("");
    printf("pre[]\t");
    for (int i = 1; i <= n; i++)
    {
        printf("%5d ", pre[i]);
    }
    puts("");
}

二、非递归

 

标签:10,结点,int,路径,迪杰,Dijkstra,算法
From: https://www.cnblogs.com/FishSmallWorld/p/17270881.html

相关文章

  • [Python3]SM3国密算法
    fromgmsslimportsm4,sm3defsm3_hash(message:str):"""国密sm3加密:parammessage:消息值,bytes类型:return:哈希值"""msg_l......
  • 负载均衡load balancing和算法介绍
    一、负载均衡介绍1.1什么是负载均衡负载均衡(loadbalancing)它是计算机的一种技术,用来在计算机集群、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到优化资源使......
  • 贪心算法
    贪心和动态规划的区别有一堆钞票,你可以拿走十张,如果想达到最大的金额,你要怎么拿?【贪心】--指定每次拿最大的,最终结果就是拿走最大数额的钱。(每次拿最大的就是局部最优......
  • 【算法】笔记
    初心:最开始出发的原因论文的代码复现也就是算法及其实现,需要精通算法学习完算法的基础知识,大致了解什么是算法以及有哪些算法目标拆分采用28法则分析事物的本质,......
  • 分布式技术原理与算法解析 04 - 存储&高可靠
    分布式存储分布式数据复制技术常用于数据备份同步复制技术注重一致性,用户请求更新数据库时,主数据库要同步到备数据库后才结束阻塞返回给用户异步复制技术注重可用......
  • 基于注水算法的MIMO信道容量matlab仿真
    1.算法描述MIMO无线通信技术源于天线分集与智能天线技术,具有二者的优越性,MIMO系统的发射端与接收端都采用多天线单元,MIMO系统具有抑制干扰、抗多径衰落等特征。使用MIMO技......
  • 基于注水算法的MIMO信道容量matlab仿真
    1.算法描述      MIMO无线通信技术源于天线分集与智能天线技术,具有二者的优越性,MIMO系统的发射端与接收端都采用多天线单元,MIMO系统具有抑制干扰、抗多径衰落等特征......
  • m基于C3D-hog-GRNN广义回归神经网络模型的人员异常行为识别算法的matlab仿真
    1.算法描述      实时的人群异常行为识别是一项极具挑战的工作,具有较高的现实意义和社会需求,快速准确地判断出异常行为并及时预警,一直是我们探索的方向。传统的机器......
  • matlab代码:基于麻雀搜索算法的无线传感器网络3D-Dvhop定位算法
    matlab代码:基于麻雀搜索算法的无线传感器网络3D-Dvhop定位算法-在三维空间中,利用麻雀搜索算法寻找未知节点到锚节点的实际距离和估计距离之间的最小误差,完成对未知节点位......
  • Matlab 车辆配送路径规划问题 四大算法解决旅行商问题(TSP) CVRP CDVRP VRPTW
    Matlab车辆配送路径规划问题四大算法解决旅行商问题(TSP) CVRPCDVRPVRPTWtsp:旅行商问题,寻找最短闭合路径cvrp:带容量约束的车辆路径规划dvrp:带距离约束的车辆路......