【数据结构】最短路径——Dijkstra算法

来源:互联网 发布:淘宝托管真的有用吗 编辑:程序博客网 时间:2024/05/21 14:41

最短路径——Dijkstra算法

设计实现有向网,针对随机有向网实例和随机源点,用Dijkstra算法求解出单源点到其他各顶点的最短路径。给出求解过程的动态演示。可考虑实现不用存储结构上的实现。


如下图所示,若要建立一个这样的图,且源点为1时,则输入顺序为:

5 7

1 2 10

1 5 100

1 4 30

2 3 50

3 5 10

4 3 20

4 5 60

1

                                                                    

代码:

#include<iostream>#include<queue>#define INF 0x3f3f3f3f//用来表示正无穷#define MAX 100 //最多可存放100个顶点using namespace std;typedef pair<int,int> P;   //用于优先队列中距离与顶点的对应,其中first为距离,second为原点到达的点bool visit[MAX];   //标记为已找出最短路径的点int v,e,s;  //v为点的个数,e为边的个数,s为源点int graph[MAX][MAX];  //图的存储采用邻接矩阵int dist[MAX];  //dist表示当前点距源点最短距离,最终为最短距离int path[MAX];void Init();//初始化void Dijkstra(const int s);void dfs(const int x);//将路径回溯出来int main(void){    int from,to,cost;    while(1)    {        cout<<"请输入点、边的个数:"<<endl;        cin>>v>>e;        Init();        cout<<"请输入每条边的起点、终点以及相应的权值:"<<endl;        for(int i=1; i<=e; i++)        {            cin>>from>>to>>cost;            graph[from][to]=cost;        }        cout<<"请输入源点:"<<endl;        cin>>s;        Dijkstra(s);        cout<<s<<"点到每个点的最短距离为:"<<endl;        for(int i=1; i<=v; i++)        {            if(dist[i]==INF)                cout<<s<<"------>"<<i<<"不可到达"<<endl;            else            {                cout<<s<<"----->"<<i<<"的最短距离为:"<<dist[i]<<endl;                cout<<"改路径为:"<<endl;                if(i==s)                    cout<<s<<"-->"<<s<<endl;                else                {                    dfs(i);//输出路径                    cout<<i<<endl;                }            }        }    }    return 0;}void Init(){    for(int i=0; i<MAX; i++)        for(int j=0; j<MAX; j++)            graph[i][j]=INF;    for(int i=0; i<MAX; i++)        dist[i]=INF;    for(int i=0; i<MAX; i++)        visit[i]=false;}void Dijkstra(const int s){    dist[s]=0;    P p;    int vi;    priority_queue <P,vector<P>,greater<P> >que;//将pair<int,int>放入优先队列,并且规定按照pair.first的较小值建立优先权    que.push(P(0,s));    while(que.size())    {        p=que.top();        que.pop();        vi=p.second;    //vi为当前源点编号        if(visit[vi])            continue;        visit[vi]=true;        for(int i=1; i<=v; i++)        {            if(!visit[i]&&dist[i]>dist[vi]+graph[vi][i])  //查找vi的相邻顶点            {                dist[i]=dist[vi]+graph[vi][i];                path[i]=vi;//i点的父亲节点为vi                que.push(P(dist[i],i));            }        }    }}void dfs(const int x){    if(x==s) //如果找到起点,就返回        return;    else        dfs(path[x]);//否则继续深搜    cout<<path[x]<<"-->";}