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

本文介绍如何使用Dijkstra算法解决单源点到其他各顶点的最短路径问题。通过C++代码实现了随机有向图的构建,并演示了算法的具体应用过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最短路径——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]<<"-->";
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值