迪杰斯特拉--记录路径

迪杰斯特拉记录路径的办法就是开一个数组, 记录一下该节点的上一个节点是谁最后在递归输出就可以了

例题:

B. wzy的大冒险——出发咯QAQ

单点时限: 2.0 sec

内存限制: 512 MB

wzy踏上了冒险的旅程。
现在他从地精手里买了一份地图,地图上有n个城镇。
他从第一个城镇出发,走向(没钱只能走)第n个城镇,现在,请你帮wzy找到一条最短的路径,并倒序(从n到1)输出一条最短路径。
举个栗子:如果有两条路径6 4 3 1和6 5 2 1,我们选择6 4 3 1这条。
地精小提示:路是单向的QAQ。

输入格式

第一行两个数n,m ,(1≤n≤103,1≤m≤103)

接下来m行,每行三个数x,y,z,表示点 x 与点 y 之间有一条权值为 z 的有向边 (1≤x,y,z≤103).

输出格式

第一行一个整数表示 1 到 n 的最短距离;
第二行倒序输出这条路径。

样例

input

5 7
1 2 69
1 3 87
1 4 79
2 5 94
2 3 10
3 5 79
4 5 43

output

122
5 4 1
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=1E4+7;
const int INF=0x3f3f3f3f;
int map[N][N];
int dis[N];
int pre[N];
int mark[N];
int n,m;
void djstrea(int x){
    memset(mark,0,sizeof(mark));
    for(int i=1;i<=n;i++){
        dis[i]=map[x][i];
    }
    dis[x]=0;
    mark[x]=1;
    for(int i=1;i<=n;i++){
        int ans=INF;
        int pos;
        for(int i=1;i<=n;i++){
            if(mark[i]==0&&ans>dis[i]){
                ans=dis[i];
                pos=i;
            }
        }
        mark[pos]=1;
        for(int i=1;i<=n;i++){
            if(dis[i]>ans+map[pos][i]){
                dis[i]=ans+map[pos][i];
                pre[i]=pos;//先到pos再到i,因此i是pos的父节点
            }
        }
     }
}
int main(){

    cin>>n>>m;
    int x,y,z;
    for(int i=0;i<=n;i++){
        pre[i]=-1;
    }
    memset(map,INF,sizeof(map));
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&x,&y,&z);
        map[x][y]=z;//本题目是单向的
    }
    djstrea(1);
    cout<<dis[n]<<endl;
    for(int i=n;i!=-1;i=pre[i]){
        cout<<i<<" ";
    }
    cout<<1<<endl;//起点
    return 0;
}

地杰斯特拉(堆优化+路径记录)

还是这个题目:题目中的队列保持的是点x,与点x到起点的距离,然后优先队列,没词都取出来较小的一个

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const int N=1E5+7;
const int INF=0x3f3f3f3f;
typedef long long ll;
struct stu{
    ll a,b;
};
int pre[N];
ll dis[N];
int mark[N];
vector<stu>ve[N];
struct node{
    int x,y;
    bool friend operator<(const node x1,const node y1){
        return x1.y>y1.y;
    }
};

void djstrea(int s){
    memset(mark,0,sizeof(mark));
    memset(dis,INF,sizeof(dis));
    priority_queue<node>que;
    dis[s]=0;
    que.push({s,0});
    while(que.size()){
        node xx=que.top();
        que.pop();
        if(mark[xx.x]==1) continue ;
        mark[xx.x]=1;
        for(int i=0;i<ve[xx.x].size();i++){
            int dx=ve[xx.x][i].a;
            int dy=ve[xx.x][i].b;
            if(mark[dx]==0&&dis[dx]>dis[xx.x]+dy){
                dis[dx]=dis[xx.x]+dy;
                if(mark[dx]==0)
                {
                    que.push({dx,dis[dx]});
                    pre[dx]=xx.x;
                }
            }
        }
    }    

}

int main(){
    int n,m,s;
    cin>>n>>m;
    s=1;
    for(int i=0;i<=n;i++)
        pre[i]=-1;
        int x,y,z;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&z);
            ve[x].push_back({y,z});

        }
        djstrea(s);
        cout<<dis[n]<<endl;
        for(int i=n;i!=-1;i=pre[i]){
            cout<<i<<" ";
        }    

    return 0;
}


原文地址:https://www.cnblogs.com/Accepting/p/11334875.html

时间: 2024-10-06 23:13:57

迪杰斯特拉--记录路径的相关文章

迪杰斯特拉算法(计算路径)

package com.rao.graph; import java.util.LinkedList; import java.util.List; /** * @author Srao * @className DijkstraWithPath * @date 2019/12/11 17:59 * @package com.rao.graph * @Description 迪杰斯特拉算法(计算路径) */ public class DijkstraWithPath { /** * 图的顶点 *

bfs输出路径 &amp;&amp; 最短路(迪杰斯特拉)输出路径

问题描述 解决方法 1.像第一个问题那就是最短路问题(我代码采用迪杰斯特拉算法)实现 2.换乘次数最少,那就用bfs广搜来寻找答案.但是我的代码不能保证这个最少换乘是最短路程 代码 1 #include<stdio.h> 2 #include<iostream> 3 #include<algorithm> 4 #include<string.h> 5 #include<queue> 6 #include<vector> 7 using

迪杰斯特拉算法介绍

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算). 此外,引进两个集合S和U.S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的顶点(以及该顶点到起点s的距离). 初始时,S中只有起点s:U中是除s之外的顶点,并且U中顶点的路径是"起点s

迪杰斯特拉(Dijkstra)算法

1 # include <stdio.h> 2 3 # define MAX_VERTEXES 20//最大顶点数 4 # define INFINITY 65535;//代表∞ 5 6 typedef struct 7 {/* 无向图结构体 */ 8 int vexs[MAX_VERTEXES];//顶点下标 9 int arc[MAX_VERTEXES][MAX_VERTEXES];//矩阵 10 int numVertexes, numEdges;//顶点数和边数 11 12 }MGra

最短路径之迪杰斯特拉(Dijkstra)算法

对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点为源点,最后一个顶点为终点.最短路径的算法主要有迪杰斯特拉(Dijkstra)算法和弗洛伊德(Floyd)算法.本文先来讲第一种,从某个源点到其余各顶点的最短路径问题. 这是一个按路径长度递增的次序产生最短路径的算法,它的大致思路是这样的. 初始时,S中仅含有源.设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度.D

十大基础实用算法之迪杰斯特拉算法、最小生成树和搜索算法

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算). 此外,引进两个集合S和U.S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的顶点(以及该顶点到起点s的距离). 初始时,S中只有起点s:U中是除s之外的顶点,并且U中顶点的路径是"起点s

普里姆算法,克鲁斯卡尔算法,迪杰斯特拉算法,弗洛里德算法

做数据结构的课程设计顺便总结一下这四大算法,本人小白学生一枚, 如果总结的有什么错误,希望能够告知指正 普里姆算法如图所示prim 找出最短的边,再以这条边构成的整体去寻找与之相邻的边,直至连接所有顶点,生成最小生成树,时间复杂度为O(n2) 克鲁斯卡尔算法如图所示kruskal 克鲁斯卡尔算法,假设连通网N=(N,{E}),则令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),图中每个顶点 自成一个连通分量.在E中选择代价最小的边,若该边依附的定顶点落在T中不同的连通分量上,

43. 蛤蟆的数据结构笔记之四十三最短路径之迪杰斯特拉(Dijkstra )算法

43. 蛤蟆的数据结构笔记之四十三最短路径之迪杰斯特拉(Dijkstra )算法 本篇名言:"辛勤的蜜蜂永没有时间悲哀.--布莱克" 这次来看下Dijkstra )算法.还是老方法,先原理,后实现.代码来自网络. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47046031 1.  最短路径 最短路径问题是图论研究中的一个经典算法问题, 旨在寻找图(由结点和路径组成的)中两结点之间的最短路径. 管道铺设.线路安排

中兴捧月算法精英挑战赛-迪杰斯特拉派

赛题为: 最强大脑中的收官蜂巢迷宫变态级挑战,相信大家都叹为观止!最强大脑收官战打响后,收视率节节攀升,就连蚁后也不时出题难为一下她的子民们.在动物世界中,称得上活地图的,除了蜜蜂,蚂蚁当仁不让.在复杂多变的蚁巢中, 蚂蚁总是能以最快.最高效的方式游历在各个储藏间(存储食物).今天,她看完最新一期节目,又发布了一项新任务:小蚁同学,我需要玉米库的玉米,再要配点水果,去帮我找来吧.小蚁正准备出发,蚁后又说:哎呀,回来,我还没说完呢,还有若干要求如下: 1.小蚁同学,你需要尽可能以最少的花费拿到食物