首页 > 其他分享 >Dijkstra基本内容

Dijkstra基本内容

时间:2024-01-17 22:55:06浏览次数:27  
标签:基本 Node head int Dijkstra maxn 内容 dis

众所周知,Dijkstra算法是一个十分有效且常用的算法. 既然说了,

有效且常用

那我们就有课学习的必要了呀!

话不多说,开始讲解.

概念

1.是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。Dijkstra算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止

2.Dijkstra 用来解决边权全为正(不能为负! ! ! ! ! ! )的单源最短路问题,Dijkstra算法又分为朴素Dijkstra算法和堆优化的Dijkstra算法。朴素版的Dijkstra算法的时间复杂度是O(n²),适合于稠密图,堆优化版的Dijkstra算法的时间复杂度是O(mlogn),适合于稀疏图。

——————————————分界线————————————————

代码讲解


#define MOD 10000000007
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=2000005;
int n,m,s;
int idx=1,e[maxn],w[maxn],head[maxn],ne[maxn];
int dis[maxn],vis[maxn];

MOD和INF不做过多解释,重点看e,w,head和ne数组


void add(int a,int b,int c)
{
	e[idx]=b;
	w[idx]=c;
	ne[idx]=head[a];
	head[a]=idx++;
}

这是一个简单的链式前向星,虽然有些奇怪的东西.

a是该点的位置,b是与该点相连的一点的位置,c则是边全
权. 我们可以看到,e数组存储了一个点到另一个点的的终点,w存储了这两个点中边的边权,ne和head数组则是普通的链式前向星啦!

恭喜你,已经学会一半了,加油!

我们再来看一组代码


struct Node
{
	int dis,x;
	bool operator<(Node p)const{return dis>p.dis;}
	Node(int dis,int x):dis(dis),x(x){}
};

我们使用重载运算符 operator 重新定义“<”符号来对边权进行排序,方便我们接下来的操作. 下面的一行可有可无,主要是装


void dijstra()
{
    memset(dis,INF,sizeof(dis));
    priority_queue<Node>q;
    dis[s]=0;
    Node u(dis[s],s);
    q.push(u);
    while(!q.empty())
    {
	Node u=q.top();
    	q.pop();
	if(vis[u.x])continue;
	vis[u.x]=1;
	for(int i=head[u.x];i!=-1;i=ne[i])
	{
	    if(dis[e[i]]>dis[u.x]+w[i])
	    {
		dis[e[i]]=dis[u.x]+w[i];
		Node v(dis[e[i]],e[i]);
		q.push(v);
	    }
	}
    }
}

这就是程序的主题了!

首先定义大根堆 priority_queue ,方便我们接下来的操作,其次,我们从s点出发,那距离s点的最短距离肯定是0,这就是 dis[s]=0的原因.

跟图有关,那我们就得使出万能且高效的

BFS!!!

如你所见,一个BFS遍历

while循环的前四行为基操,不做过多讲述,我们来看for循环


for(int i=head[u.x],i!=-1;i=ne[i])

从第x个点的链下标出发,向下一个点,也就是ne[i]前进,但由于我们标记了每一个点初始值为-1,所以还得判断一下


if(dis[e[i]]>dis[u.x]+w[i])
{
    dis[e[i]]=dis[u.x]+w[i];
    Node v(dis[e[i]],e[i]);
    q.push(v);
}

这里我们做出判断,如果新路径的边权总和小于原路径边权总和,就改变最佳路经

圆满结束

这里附上完整代码:


#include<bits/stdc++.h>
#define MOD 10000000007
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=2000005;
int n,m,s;
int idx=1,e[maxn],w[maxn],head[maxn],ne[maxn];
int dis[maxn],vis[maxn];
struct Node
{
	int dis,x;
	bool operator<(Node p)const{return dis>p.dis;}
	Node(int dis,int x):dis(dis),x(x){}
};

inline int read()
{
	int date=0,w=1;
	char c;
	c=getchar();
	while(c<'0' || c>'9')
	{
		if(c=='-')w=-1;
		c=getchar();
	}
	while(c>='0' && c<='9')
	{
		date=date*10+(c-'0');
		c=getchar();
	}
	return date*w;
}

void add(int a,int b,int c)
{
	e[idx]=b;
	w[idx]=c;
	ne[idx]=head[a];
	head[a]=idx++;
}

void dijstra()
{
	memset(dis,INF,sizeof(dis));
	priority_queue<Node>q;
	dis[s]=0;
	Node u(dis[s],s);
	q.push(u);
	while(!q.empty())
	{
		Node u=q.top();
		q.pop();
		if(vis[u.x])continue;
		vis[u.x]=1;
		for(int i=head[u.x];i!=-1;i=ne[i])
		{
			if(dis[e[i]]>dis[u.x]+w[i])
			{
				dis[e[i]]=dis[u.x]+w[i];
				Node v(dis[e[i]],e[i]);
				q.push(v);
			}
		}
	}
}
signed main()
{
	memset(head,-1,sizeof(head));
	n=read(),m=read(),s=read();
	for(int i=1;i<=m;i++)
	{
		int a=read(),b=read(),c=read();
		add(a,b,c);
	}
	dijstra();
	for(int i=1;i<=n;i++)
		cout<<dis[i]<<" ";
	return 0;
}

dijkstra例题

友情提醒:本人为 ju ruo ,若觉得本文不够清晰的话,建议去寻找其他资源

感谢您的观看!

标签:基本,Node,head,int,Dijkstra,maxn,内容,dis
From: https://www.cnblogs.com/MarsNotFound/p/17971405

相关文章

  • 实时云渲染:流式传输 VR 和 AR 内容
    想象一下无需专用的物理计算机,甚至无需实物连接,就能获得高质量的AR/VR体验是种什么样的体验?过去,与VR交互需要专用的高端工作站,并且根据头显、壁挂式传感器和专用的物理空间。VR中的复杂任务会突破传感器范围、电缆长度和空间边界的限制,使艺术家陷入困境并限制他们的行动。该......
  • 阿里云云原生专场精彩内容集锦丨2023 云原生产业大会
    2023云原生产业大会已于昨日闭幕,在阿里云云原生专场,来自阿里云的多位技术专家、中国信通院云大所副总工程师陈屹力及安永科技咨询合伙人王祺都带来了精彩的分享。关注公众号,后台回复:1201免费获得阿里云云原生专场 PPT合辑本次大会正值云原生技术规模化应用的关键时期,国内外云原......
  • 阿里云云原生专场精彩内容集锦丨2023 云原生产业大会
    2023云原生产业大会已于昨日闭幕,在阿里云云原生专场,来自阿里云的多位技术专家、中国信通院云大所副总工程师陈屹力及安永科技咨询合伙人王祺都带来了精彩的分享。关注公众号,后台回复:1201免费获得阿里云云原生专场 PPT合辑本次大会正值云原生技术规模化应用的关键时期,国内外......
  • 基于内容的电影推荐算法研究
    引言今天读的文章为一篇名为《基于内容的电影推荐算法研究》的文章,文章提出了一种基于内容的电影推荐算法,通过分析电影特征和用户兴趣,实现更精准的电影推荐。文章中使用到了TF-IDF向量化方法,将电影类型和导演信息转化为特征向量,然后使用余弦相似度来衡量电影之间的相关性,接下来......
  • mysql基本数据类型范围与存储说明
    一、整型数据类型存储方式整型数据类型是Mysql中最常用的数据类型之一,其存储方式如下:(默认是有符号,即取值范围是正负范围;无符号,即取值范围就是正值范围)1.TINYINT:占用1个字节,范围为-128~127。2.SMALLINT:占用2个字节,范围为-32768~32767。3.MEDIUMINT:占用3个字节,范围为-8388608~8......
  • eNSP模拟实验——OSPF基本配置
    1.利用eNSP搭建网络拓扑,并对三个主机进行基础配置,包括IP地址、子网掩码、网关。配置完成后,全选启动设备。如果启动设备速度过慢,可以一个一个启动。其中,所有路由器选择AR2220,所有接口的掩码地址统一配置成255.255.255.0。 2.配置三个路由器各自物理接口的IP地址,其中每个路由......
  • [Java]关于基本数据类型与引用类型赋值时的底层分析的小结(简述)
    【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)https://www.cnblogs.com/cnb-yuchen/p/17969159出自【进步*于辰的博客】目录1、关于赋值1.1基本数据类型赋值1.2String类型赋值2、关于String赋值2.1情形一2.2情形二3、关于String与char[]的比较4、不同类型引......
  • 20230116python基本语法day1
    20230116python基本语法day1代码看一行写一行。菜鸟教程python3成为自己尊重自己欣赏的自己。注意点:python中,#TODO待处理,显示为黄色,这边的问题要在最后解决掉,这很重要。在java中可能是//TODO    解释器的作用是运行文件,给代码解释文件。......
  • 基本的Dos命令
    打开cmd的方式:开始+系统文件夹+命令提示符Win键+R,然后输入cmd打开控制台(推荐使用)在桌面下,按住shift键+鼠标右键点击,然后点击“在此处打开Powershell窗口”,打开命令行窗口资源管理器的地址栏前面加上cmd+空格+任意路径管理员方式运行:使用上述第一种方法,选择管理员方式运行......
  • FastAPI学习-30 项目代码中添加自己的日志内容
    前言前面一篇【FastAPI学习-29uvicorn使用log_config参数设置logger日志格式】已经学会了配置uvicorn的日志。如何在fastapi项目代码中添加自己的日志呢?添加日志创建一个logger实例,名称为"fast"fromfastapiimportFastAPIimportlogginglogger=logging.getLo......