迪杰斯特拉--记录路径

Posted accepting

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了迪杰斯特拉--记录路径相关的知识,希望对你有一定的参考价值。

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

例题:

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

单点时限: 2.0 sec

内存限制: 512 MB

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

输入格式

第一行两个数n,m ,(1n103,1m103)

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

输出格式

第一行一个整数表示 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;

 



以上是关于迪杰斯特拉--记录路径的主要内容,如果未能解决你的问题,请参考以下文章

迪杰斯特拉算法为啥不能有负权边

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

图论——迪杰斯特拉算法和最小生成树

求多重邻接表的迪杰斯特拉算法

图的应用——最短路径(迪杰斯特拉算法)

Dijkstra迪杰斯特拉算法