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

来源:互联网 发布:如何管理淘宝网店 编辑:程序博客网 时间:2024/06/06 12:25

如果要了解过程http://blog.csdn.net/cjc211322/article/details/24933909 

关于路径保存方法http://blog.csdn.net/jinixin/article/details/52247763 

算法思想:

首先了解这是一个不可以求负权的单源最短路径算法,以贪心的思想,每次寻找一个距离源点最近且没有标记过的节点,然后标记(注意自己到自己的距离置为0),对该节点进行松弛操作,如果可以进行,就保存路径(要求路径的话),最后用栈还原路径

题目:

wust oj上的一题:1868

1868: 最短路径

Time Limit: 1 Sec  Memory Limit: 128 MB  64bit IO Format: %lld
Submitted: 23  Accepted: 19
[Submit][Status][Web Board]

Description

 有n个城市(编号从1到n),个城市之间都有路连接,切这些路都是单向的。每条路都有相应的长度。各城市之间构成的路网不可能构成环状。没有一条路到达城市1,所有城市都能够到达城市n。城市n不能到达其它任何城市。

Input

第一行包含一个整数n,表示城市数目。

接下来包含n行,每行n个整数。第i行第j列的整数a[i][j]表示城市i和城市j的路径长度。

100 2 5 1 0 0 0 0 0 00 0 0 0 12 14 0 0 0 00 0 0 0 6 10 4 0 0 00 0 0 0 13 12 11 0 0 00 0 0 0 0 0 0 3 9 00 0 0 0 0 0 0 6 5 00 0 0 0 0 0 0 0 10 00 0 0 0 0 0 0 0 0 50 0 0 0 0 0 0 0 0 20 0 0 0 0 0 0 0 0 0

Output

第一行输出最短路径长度,形如minlong=最短路径长度值“”。

接下来的一行输出从第1个城市到第n个城市的最短路径上的所有城市。(详见样例)

minlong=191 3 5 8 10

代码:

#include<algorithm>#include<iostream>#include<cstring>#include<stdio.h>#include<math.h>#include<string>#include<stdio.h>#include<queue>#include<stack>#include<map>#include<deque>using namespace std;int p[105][105],path[105];int dis[105],vis[105],n;const int INF=1008611;void init(){    int i,j;    for(i=1;i<=n;i++)    {        for(j=1;j<=n;j++)        {            scanf("%d",&p[i][j]);            if(p[i][j]==0)                p[i][j]=INF;//不连通的点值路径值为inf        }        vis[i]=0;//判断是否遍历该节点的数组        path[i]=-1;//前继节点初始为-1    }}void dj(){    int i,j,k,minn,key;    for(i=1;i<=n;i++)    {        dis[i]=INF;//初始化距离    }    dis[1]=0;    for(i=1;i<=n;i++)    {        minn=INF;        for(j=1;j<=n;j++)//贪心查找一个没有遍历过的距离最小的节点        {            if(!vis[j]&&minn>dis[j])            {                minn=dis[j];                key=j;            }        }       vis[key]=1;//标记        for(j=1;j<=n;j++)        {            if(minn+p[key][j]<dis[j])//对该节点进行松弛操作            {                path[j]=key;//记录路径                dis[j]=minn+p[key][j];            }        }    }}void print(){    int i=n,j;    stack<int>q;    while(path[i]!=-1)//用栈来实现路径还原    {        q.push(i);        i=path[i];    }    q.push(i);    while(!q.empty())    {        printf("%d",q.top());        q.pop();        if(!q.empty())            printf(" ");    }    printf("\n");}int main(){    int i,j;    while(scanf("%d",&n)!=EOF)    {        init();        dj();        printf("minlong=%d\n",dis[n]);        print();    }    return 0;}





原创粉丝点击