首页 > 编程语言 >最短路径Dijkstra算法--求距离和路径

最短路径Dijkstra算法--求距离和路径

时间:2023-08-06 16:32:13浏览次数:29  
标签:node dijk -- 路径 int Dijkstra vector include adj

1、题目描述 求单条路线

最短路径Dijkstra算法--求距离和路径_i++

最短路径Dijkstra算法--求距离和路径_ci_02

2、AC代码
#include <iostream>
#include<cstring>
#include<bits/stdc++.h>
#define inf 1000000000
using namespace std;
typedef long long ll;
const int N=105;
int n,m,s,t;

struct node
{
	int v; // 边终点
	int w;// 边权
	node(int x,int y):v(x),w(y){
	}
};
vector<node> adj[N];
int d[N],pre[N];
bool vis[N];
void dijk(int S)
{
	fill(d,d+N,inf);
	//fill(num,num+N,0);
	d[S]=0;
	
	for(int i=0;i<n;i++)
	{
		int u=-1,min=inf;
		for(int j=0;j<n;j++)
		{
			if(!vis[j] && d[j] < min)
			{
				min=d[j];
				u=j;
			}
		}
		if(u==-1)return;
		vis[u]=true;
		for(int j=0;j<(int)adj[u].size();j++)
		{
			int v = adj[u][j].v; // 获取边的终点 
			if(!vis[v])
			{
				if(d[u] + adj[u][j].w < d[v])
				{
					d[v] = d[u] + adj[u][j].w;
					pre[v] = u; //记录v的前驱
				}
			}
		}
	}
}
// 递归输出路径
void dfs(int v)
{
	if(v==s)
	{
		cout<<s<<"->";
		return;
	}
	dfs(pre[v]);
	cout<<v;
	if(v!=t)
	{
		cout<<"->";
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	
	cin>>n>>m>>s>>t;
	int u,v,w;
	for(int i=0;i<m;i++)
	{
		cin>>u>>v>>w;
		adj[u].push_back(node(v,w));
		adj[v].push_back(node(u,w));
	}
	dijk(s);
	
	cout<<d[t]<<" ";
	dfs(t);
  	return 0;
}
2、求多条路线

最短路径Dijkstra算法--求距离和路径_#include_03

最短路径Dijkstra算法--求距离和路径_#include_04

#include <iostream>
#include<cstring>
#include<bits/stdc++.h>
#define inf 1000000000
using namespace std;
typedef long long ll;
const int N=105;
int n,m,s,t;

struct node
{
	int v; // 边终点
	int w;// 边权
	node(int x,int y):v(x),w(y){
	}
};
vector<node> adj[N];
int d[N];
bool vis[N];
vector<int> pre[N]; //记录前驱
vector<int> tpath; // 记录当前的路径
vector<vector<int>> paths; //记录所有最短路径 
void dijk()
{
	fill(d,d+N,inf);
	d[s]=0;
	
	for(int i=0;i<n;i++)
	{
		int u=-1,min=inf;
		for(int j=0;j<n;j++)
		{
			if(!vis[j] && d[j] < min)
			{
				min=d[j];
				u=j;
			}
		}
		if(u==-1)return;
		vis[u]=true;
		for(int j=0;j<(int)adj[u].size();j++)
		{
			int v = adj[u][j].v; // 获取边的终点 
			int w = adj[u][j].w;
			if(!vis[v])
			{
				if(d[u] + w < d[v])
				{
					d[v] = d[u] + w;
					pre[v].clear(); // 因为有更优的路径,所以清空之前的
					pre[v].push_back(u); // 记录v的前驱u 
				}else if(d[u] + w == d[v])
				{
					pre[v].push_back(u);
				}
			}
		}
	}
}
void dfs(int v)
{
	if(v==s) // 到达起点 
	{
		tpath.push_back(v); // 当前路线添加上起点 
		paths.push_back(tpath); // 记录当前路线信息
		tpath.pop_back(); //清空当前路线的起点 
		return;
	}
	tpath.push_back(v);
	for(int i=0;i<(int)pre[v].size();i++)
	{
		dfs(pre[v][i]);
	}
	tpath.pop_back(); //清空当前路线 
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	
	cin>>n>>m>>s>>t;
	int u,v,w;
	for(int i=0;i<m;i++)
	{
		cin>>u>>v>>w;
		adj[u].push_back(node(v,w));
		adj[v].push_back(node(u,w));
	}
	dijk();
	dfs(t);
	cout<<paths.size()<<endl;
	for(int i=0;i<paths.size();i++)
	{
		reverse(paths[i].begin(),paths[i].end()); // 因为每一条路线信息是倒过来的,所以需要先逆序 
	}
	sort(paths.begin(),paths.end()); // 对所有路线进行排序
	for(int i=0;i<paths.size();i++)
	{
		for(int j=0;j<paths[i].size();j++)
		{
			cout<<paths[i][j];
			if(j<paths[i].size()-1)cout<<"->";
		}
		cout<<endl;
	} 
  	return 0;
}

标签:node,dijk,--,路径,int,Dijkstra,vector,include,adj
From: https://blog.51cto.com/u_16200950/6985165

相关文章

  • ChatGPT:怎样打造智能客服体验的重要工具?
    ChatGPT:人工智能的交互式对话伙伴"可以理解为以下几个方面:1.ChatGPT:ChatGPT是一个人工智能系统,专门设计用于进行对话和交流。它基于自然语言处理和深度学习技术,能够理解人类的语言输入并做出相应的回应。2.人工智能的:ChatGPT是由人工智能技术驱动的,它通过算法和模型来模拟人类的对......
  • 线程
    程序、进程、线程程序:为完成某些特定任务,用某种语言编写的一组指令的集合,代码进程:程序的一次执行过程,正在运行的一个程序【这是一个动态过程,产生,存在,完成某些功能,消亡】线程:由进程创建的,是进程的一个实体,一个进程可以拥有多个线程【举个例子:一个正在读书并同时听音乐的人正在努力学......
  • 什么是向量数据库
    在计算机科学中,向量数据库是一种专门用于存储和管理向量数据的数据库系统。向量数据库与其他数据库系统的主要区别在于,它使用向量运算来计算数据之间的相似度,而不是基于文本的查询语言。这种计算方式使得向量数据库在处理高维数据和复杂的语义时具有更高的效率和准确性。向量数据......
  • #888
    //A#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintN=1e6+10,mod=1e9+7;strings;intn,t,a[N],f[N],res,num,ans,m,k,p;boolvis[N];signedmain(){std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>......
  • VIM进阶学习笔记(二) 总结复习vim的移动光标导航
    惊闻vim作者BramMoolenaar去世,享年62岁。唉,这vim还没学会,太遗憾了。。。几十年致力于这么伟大的工具开发,令人敬佩。致敬。 个人从vim大致入门后,使用了基本配置vim操作体验来看,vim是在Linux等命令行界面,以及鼠标还未普及的情况下,使得通过纯键盘操作达到十分便捷的强大编......
  • VBA对=的解释
    在VBE中,=运算符的解释取决于它在表达式中的上下文。赋值运算符:当=运算符用于将右侧的值赋给左侧的变量时,它被解释为赋值运算符。例如:a=10'将10赋值给变量a判断运算符:当=运算符用于比较两个值是否相等时,它被解释为判断运算符。例如:Ifa=10Then'如果a等于10,则执行......
  • 左值,右值,引用,指针,常量,auto如何组合?
    左值,右值,引用,指针,常量,auto如何组合?左值引用:int&a=b;左值引用是通过使用&符号来声明的,例如int&a。左值引用用于绑定到左值(可标识的、持久的、具名的),a绑定到b。左值引用允许对其绑定的对象进行修改。使用左值引用可以实现函数参数的传递和返回值的传递,以及在函数中进行......
  • 聊聊测试开发工程师的职责定位问题
    网上有人会把测开定位成为测试工具开发,主要是开发自动化测试工具或平台,用以帮助手动验收的同学提升效率。存在即合理,确实有一些团队或组织是这样建设的。但作为行业从业者,我们也应该认识到,这样是不全面的,有误导之嫌。现实中的绝大部分测开还是定位在保障业务迭代质量上,因为这......
  • 深度 Q 网络(deep Q network,DQN)原理&实现
    深度Q网络(deepQnetwork,DQN)原理&实现1Q-Learning算法1.1算法过程Q-learning是一种用于解决强化学习问题的无模型算法。强化学习是一种让智能体学习如何在环境中采取行动以最大化某种累积奖励的机器学习方法。在Q-learning中,智能体根据称为Q-values的函数来选择行动。Q-v......
  • python配置
    python配置pip设置全局清华源pipconfigsetglobal.index-urlhttps://pypi.tuna.tsinghua.edu.cn/simplejupyter安装pipinstalljupyterlabjupyter内核配置pipinstallipykernelpython-mipykernelinstall--user--name=yolov8jupyterkernelspeclistjupyter......