首页 > 其他分享 >TZOJ 7685: 最短路径 (dijstra/输出路径pre)

TZOJ 7685: 最短路径 (dijstra/输出路径pre)

时间:2022-10-10 15:11:40浏览次数:40  
标签:pre int 路径 pos 最短 dijstra dis

描述

 

 

给定n个顶点的带权有向图,若从顶点x到顶点y之间存在一条路径,那么这条路径的长度定义为路径上各条边的权值之和。

现在请你找出从顶点1到顶点n的一条最短路径。

 

 

输入

 

 

第一行为两个正整数n和m(n<=1000,m<=5000),n表示顶点数,m表示边数。

接下来有m行,每行三个正整数x,y,w,表示顶点x到y有一条边权为w的边。

1<=x, y<=n,w不大于10000。

两个顶点之间可能存在多条边。

 

 

输出

 

 

如果存在最短路径,则第一行输出最短路径长度,否则输出Sorry。

如果最短路径存在则在第二行输出一条从顶点1到顶点n之间的一条最短路径,格式如下:

1->v1->...->n

 

 

样例输入

 

4 4
1 2 3
2 3 1
2 4 4
3 4 2

样例输出

6
1->2->3->4

题解:难蚌,信奥一本通上说pre[x]来记录路径,结果代码示例的时候给我来个二维的数组,整蒙了,翻看了网上的各个代码再加上自己的排列组合才得出正确代码。。。

总结:

1.使用dijstra求最短路径时pre数组要提前设定好将pre[起点] = 0;

2.pre的更新是在dijstra更新每个点的最短距离dis[j]时,对于j点的前驱节点要更新为当前最短路节点 pre[j] = pos

3.输出最短路径时先输出起点,然后将终点传入print(终点)

4.在print方法中因为我们提前设定好了pre[起点] =0,所以递归的边界为if(pre[x]==0)return;否则继续调用,并将pre[x]传入,递归到边界返回时就可以输出每个节点了

5.对于pre[x]的意思指的是第x个节点的前驱节点;

#include<bits/stdc++.h>
using namespace std;
const int inf = 1e8+10;
int n,m,k;
int ma[1001][1001],dis[1001],vis[1001],pre[1001];
//ma地图,dis起点到某个点的距离,vis标记,pre记录每个下标节点的前驱节点 
void print(int x)
{
    if(pre[x]==0)return;
    print(pre[x]);
    cout<<"->"<<x;
}
void dijstra(int st)
{
    int pos=1,minn,sum=0;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++){
        dis[i] = ma[st][i]; //标记起点st到每个点i的距离dis[i] 
        pre[i] = st;
    }
    vis[st] = 1; //标记起点st已走过 
    dis[st] = 0; //将起点st距离设为0
    pre[st] = 0; // 将起点设为0,作为递归边界 
    for(int i=1;i<=n;i++)
    {
        minn = inf;
        for(int j=1;j<=n;j++) //找到当前起点到下一个点的最短距离minn及点位pos 
        {
            if(vis[j]==0&&minn>dis[j]) //如果j点没走过且当前最小值大于dis[j]
            {
                minn = dis[j]; //更新minn
                pos = j; //记录当前最小值下标j 
            } 
        } 
        if(minn==inf)break; //没有下一个点
        vis[pos] = 1; //将当前最短路径点pos标记
        //ans[++k] = pos;
        for(int j=1;j<=n;j++)
        {
            if(vis[j]==0&&dis[j]>dis[pos]+ma[pos][j])
                {
                    dis[j] = dis[pos]+ma[pos][j];
                    pre[j] = pos; //记录j节点的前驱节点是pos 
                }
        } 
        
    } 
    
}
int main()
{
    cin>>n>>m;
    memset(pre,0,sizeof(0));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            if(i==j) ma[i][j] = 0;
            else ma[i][j] = inf;
        }
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        if(ma[a][b]>c) ma[a][b] = c;
    }
    dijstra(1);
    if(dis[n]!=inf){
        cout<<dis[n]<<endl<<1; //输出起点 
        print(n);//把终点传入,输出路径 
    }
    else cout<<"Sorry";
     return 0;
}

 

标签:pre,int,路径,pos,最短,dijstra,dis
From: https://www.cnblogs.com/jyssh/p/16775805.html

相关文章