Dijkstra算法

1.Dijkstra算法介绍

Dijkstra是解决从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

2.算法实现

在这里插入图片描述

例如求V0到达各个节点的最短路径,我这里用的邻接表存储图,用到了STL里的优先队列,而且要进行运算符重载。
贴代码


#include<vector>
#include<iostream>
#include<queue>
using namespace std;
class road
{
public:
	int end;         //路径到达的终点
	int weight;      //路径的权重
};
class Graph
{
public:
	int v;                   //顶点个数
	int *mark;               //标记,如果已访问标记为1,否则为0
	vector<road> *adj;       //邻接表

	Graph(int n);                 //构造函数
	~Graph();                     //析构函数
	void addEdge(int b,int e,int w);        //添加边
};
Graph::Graph(int n)          //构造函数
{
	v=n;                      //顶点数
	mark=new int[n];         
	adj=new vector<road>[n];
	for(int i=0;i<n;i++)           //所有顶点标记为0
	{
		mark[i]=0;
	}
}
Graph::~Graph()          //析构函数
{
	delete [] adj;
	delete [] mark;
}
void Graph::addEdge(int b,int e,int w)   //添加一条边
{
	road r;
	r.end=e;
	r.weight=w;
	adj[b].push_back(r);
}
class Dist                     //Dist类,用于保存最短路径信息
{
public:
	int index;             //节点的索引值
	int length;            //到达改节点的长度
	int pre;               //节点的前驱
	 friend bool operator<(const Dist & a,const Dist &b)   //重载 < 
	{
		return a.length>b.length;
	}
};
void Dijkstra(Graph & g,int s)   //s是起点
{
	Dist *D=new Dist[g.v];        
	for(int i=0;i<g.v;i++)            //Dist初始化
	{
		D[i].index=i;
		D[i].length=1<<30;
		D[i].pre=s;
	}
	D[s].length=0;                   //到达起始节点路径为0
	priority_queue<Dist> aqueue;     //优先队列,找最短路径
	aqueue.push(D[s]);               //入队

	for(int i=0;i<g.v;i++)
	{
		Dist d;
		bool FOUND=false;
		while(!aqueue.empty())
		{
			d=aqueue.top();     //获得到s路径长度最小的节点
			aqueue.pop();
			if(g.mark[d.index]==0)    //找到并跳出循环
			{
				FOUND=true;
				break;
			}
		}
		if(!FOUND)   //若没有符合条件的最短路径则跳出本次循环
			break;
		int node=d.index;
		g.mark[node]=1;         //标记为1
		vector<road>::iterator ii=g.adj[node].begin();   //刷新最短路径
		for(;ii!=g.adj[node].end();ii++)
		{
			if( D[ii->end].length > D[node].length+ ii->weight )
			{
				D[ii->end].length = D[node].length+ ii->weight;
				D[ii->end].pre = node;
				aqueue.push(D[ii->end]);
			}
		}
	}
	for(int i=0;i<g.v;i++)
	{
		if(D[i].length==1<<30)
		{
			cout<<"无法到达节点:"<<D[i].index<<endl;
			continue;
		}
		cout<<"到达节点:"<<D[i].index<<" 最短路径为:"<<D[i].length<<endl;
	}
}
int main()
{
	Graph g(6);
	g.addEdge(0,1,50);
	g.addEdge(0,2,10);
	g.addEdge(1,2,15);
	g.addEdge(1,4,50);
	g.addEdge(2,0,20);
	g.addEdge(2,3,15);
	g.addEdge(3,4,35);
	g.addEdge(3,1,20);
	g.addEdge(4,3,30);
	g.addEdge(5,3,3);
	Dijkstra(g,0);
	return 0;
}

运行结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值