zoukankan      html  css  js  c++  java
  • 迪杰斯特拉--记录路径

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

    例题:

    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;
    }


  • 相关阅读:
    HDU 4348 To the moon(可持久化线段树)
    HDU 5875 Function 大连网络赛 线段树
    HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)
    HDU 5876 大连网络赛 Sparse Graph
    HDU 5701 中位数计数 百度之星初赛
    CodeForces 708B Recover the String
    Java实现 蓝桥杯 算法提高 套正方形(暴力)
    ASP.NET生成验证码
    ASP.NET生成验证码
    ASP.NET生成验证码
  • 原文地址:https://www.cnblogs.com/Accepting/p/11334875.html
Copyright © 2011-2022 走看看