最短路径 dijkstra算法实现问题总结

本文总结了Dijkstra算法在解决单源最短路径问题中的应用,包括基本模板和适用于更复杂情况的模板。在基本模板中,提供了无向图的邻接矩阵实现,并讨论了在不同条件下的优化,如输出所有最短路径、考虑边权和点权等。对于更复杂的情况,提出先用Dijkstra找出最短路径,再在这些路径中寻找符合特定条件的最优路径,使用vector记录可能的多个前驱节点,并通过DFS遍历找到最优解。代码示例包括PAT A组的1003和1030题。

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

dijkstra算法解决的是单源的最短路径问题 一般输出给定起点到其余各点的最短距离 最短的路径用pre记录前驱 用递归的方法求最短路径
在权值非负时有效
首先 给出dijkstra算法的伪代码

初始化起点 d[s]=0 ,其余为inf
for( int i=0;i<N;i++)  //有n个结点n循环n次  每次加入一个结点
{
   
	int u=-1,min=inf;
	for(int j=0;i<n;j++){
   
		找到未访问结点中  d[u]最小的那个
	}
	if(u== -1)找不到 return;
	找到 vis[u]=true;
	if(以u为中间结点  优化u所连的所有未访问的结点)
	{
   优化}

最后的d[i]记录的就是最短的路径

模板1

这是最普通的模板 之后会一点点复杂化
先贴上基本的dijkstra的代码
假设无向图已经建立好 采用邻接矩阵存

void dijkstra(int s)
{
   
    fill(d,d+maxn,inf);
    d[s]=0;
    for(int i=0;i<n;i++)
    {
   
        int u=-1;int min=inf;
        for(int j=0;j<n;j++)
        {
   
            if(vis[j]==false && d[j]<min){
   //找到未访问里面的最小的  访问他
                u=j;
                min=d[j];
            }
        }
        if(u ==-1) return ;// 未找到证明没有连通和i连通的了
        vis[u]=true;
        for(int v=0;v<n;v++){
     //以u为中介  优化未访问的结点
            if(vis[v] == false && G[u][v] != inf  &&d[u]+ G[u][v] <d[v])
            {
   
                d[v]=d[u]+G[u][v];
            }
    }
}

下面进行复杂化的模板 直接在上面的基础上更改
可能会增加以下的条件
① 最短的路径不止一条 输出所有条数
②在①的条件下 给每条边加边权(如花费 时间)优先输出边权最小的或最大的
加点权 每个点(人数 等) 输出最多的人数 等
③ 问有多少条最短路径
方法: 加边权,点权的数组 d【】 w【】 num’【】 d【】是距离 一般就是边权
只要在更新 d【v】的时候 加上即可 其余的不用改

上代码
原题 patA 1003 题目

//首先定义变量名  初始化
const int inf=100000000;
int G[maxn][maxn];
int d[maxn], w[maxn], num[maxn]; //d最短距离 w最大点权和  num最短路劲数
int n,m,st,ed,weight[maxn];

bool vis[maxn]={
   false};
void dijkstra(int s)
{
   
    fill(d,d+maxn,inf);
    memset(w,0,sizeof(d));  //点权之和为零  救助人数
    d
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值