最短路径类dijkstra算法

最短路径类dijkstra算法

一:简介

这个算法用于解决图中单源最短路径问题。所谓单源节点是指给定源节点,求图中其它节点到此源节点的最短路径。如下图所示:给定源节点a,求节点b到a的最短距离。

这里写图片描述在这里插入图片描述
算法代码

#pragma once
#include<map>
#include<vector>
#include<string>
#include<iostream>
using namespace std;
class info
{
public:
	int mindis;//记录最小的权值
	string minpath;//记录最小的权值对应的路径
	info() : mindis(INT_MAX), minpath("") {};
};
class graph
{
private:
	bool type;//记录图的类型,false为无向图,true为有向图
	int edgenum;//记录图的边数
	map<string, map<string, int>> edge;//记录图的边和对应权值
	map<string, int> arri;//记录能够到达且未被访问的点
	map<string, map<string, info>> start2end;//记录起点到终点的信息
	bool initArriveable(string start)
	{
		if (edge.find(start) != edge.end())
		{
			arri[start]=0;//放入第一个能到达的点,即起点
			info tmpinfo;
			tmpinfo.mindis = 0;//设置起点的权值为0
			tmpinfo.minpath = start;//设置起点的路径为起点本身
			start2end[start][start] = tmpinfo;//设置起点到起点的路径和权值
			return true;
		}
		return false;
	}
public:
	graph(int n,bool t=false)//初始化图的边数和图的类型
	{
		edgenum = n;
		type = t;
	}
	void inputEdge(string vex1,string vex2,int dis)
	{
		if (type)//保存有向图的边
		{
			edge[vex1][vex2] = dis;
		}
		else//保存无向图的边
		{
			edge[vex1][vex2] = dis;
			edge[vex2][vex1] = dis;
		}
	}
	
	bool dijkstra(string start)
	{
		bool flag = initArriveable(start);
		if(flag)
		{
			while (!arri.empty())
			{	
				int min=INT_MAX;
				map<string, int>::iterator itertmp;
				for (map<string, int>::iterator iter = arri.begin();iter != arri.end();iter++)
				{
					if (min > iter->second)
					{
						min = iter->second;
						itertmp = iter;//取一个权值最小的点
					}
				}
				string midvex= itertmp->first;
				arri.erase(itertmp);
				//cout << midvex << "   " << min<< endl;
				if (edge.find(midvex) != edge.end())//判断是否存在路径与权值最小的路径相连
				{
					for (map<string, int>::iterator iter = edge[midvex].begin();iter != edge[midvex].end();iter++)
					{
						int dis = start2end[start][midvex].mindis + iter->second;
						string path = start2end[start][midvex].minpath + "->" + iter->first;
						if (dis < start2end[start][iter->first].mindis)//比较新旧路径的权值
						{
							start2end[start][iter->first].mindis = dis;//用小权值替换原权值
							start2end[start][iter->first].minpath = path;//用权值小的路径替换原路径
							arri[iter->first] = dis;
						}	
					}
				}
			}
		}
		return flag;
	}
	void printMinPath(string start)
	{
		if (start2end.find(start) != start2end.end())
		{
			for (map<string, info>::iterator iter = start2end[start].begin();iter != start2end[start].end();iter++)
			{
				cout << start << "到" << iter->first << "的最短路径为:" << iter->second.minpath << ",最短距离为:" << iter->second.mindis << endl;
			}
		}
		else
		{
			if (dijkstra(start))
			{
				printMinPath(start);
			}
		}
	}
	void printMinPath(string start,string end)
	{
		if (start2end.find(start) != start2end.end())
		{
			if(start2end[start].find(end)!= start2end[start].end())
			{
				cout << start << "到" << end << "的最短路径为:" << start2end[start][end].minpath << ",最短距离为:" << start2end[start][end].mindis << endl;
			}
			else
			{
				cout << start << "到" << end << "的最短路径为:" << "不存在" << ",最短距离为:" << "∞" << endl;
			}
		}
		else
		{
			if (dijkstra(start))
			{
				printMinPath(start,end);
			}
		}
	}
};
**测试代码**

#include"graph.h"
#include"windows.h"
int main()
{
	int m;
	string vex1, vex2, wight;
	string begin,end;
	cout << "请输入边数:" << endl;
	cin >> m;
	graph g(m);
	cout << "请输入边的端点和距离:" << endl;
	while (m)
	{
		cin >> vex1 >> vex2 >> wight;
		g.inputEdge(vex1, vex2, atoi(wight.c_str()));
		m--;
	}
	while (1)
	{
		cout << "请输入起点:" << endl;
		cin >> begin;
		if (begin=="end")
		{
			break;
		}
		g.printMinPath(begin);		
	}
	while (1)
	{
		cout << "请输入起点和终点:" << endl;
		cin >> begin >> end;
		if (begin == "end")
		{
			break;
		}
		g.printMinPath(begin,end);
	}
	system("pause");
	return 0;
}
**测试数据**
22
a b 12
b c 2
c f 3
f i 1
h i 8
g h 5
g d 1
a d 3
a e 1
b e 1
c e 6
f e 10
i e 11
h e 2
g e 3
d e 7
g j 2
h j 5
i j 3
k l 3
k a 4
l d 5

**测试结果**
请输入起点:
a
a到a的最短路径为:a,最短距离为:0
a到b的最短路径为:a->e->b,最短距离为:2
a到c的最短路径为:a->e->b->c,最短距离为:4
a到d的最短路径为:a->d,最短距离为:3
a到e的最短路径为:a->e,最短距离为:1
a到f的最短路径为:a->e->b->c->f,最短距离为:7
a到g的最短路径为:a->e->g,最短距离为:4
a到h的最短路径为:a->e->h,最短距离为:3
a到i的最短路径为:a->e->b->c->f->i,最短距离为:8
a到j的最短路径为:a->e->g->j,最短距离为:6
a到k的最短路径为:a->k,最短距离为:4
a到l的最短路径为:a->k->l,最短距离为:7
请输入起点:
b
b到a的最短路径为:b->e->a,最短距离为:2
b到b的最短路径为:b,最短距离为:0
b到c的最短路径为:b->c,最短距离为:2
b到d的最短路径为:b->e->a->d,最短距离为:5
b到e的最短路径为:b->e,最短距离为:1
b到f的最短路径为:b->c->f,最短距离为:5
b到g的最短路径为:b->e->g,最短距离为:4
b到h的最短路径为:b->e->h,最短距离为:3
b到i的最短路径为:b->c->f->i,最短距离为:6
b到j的最短路径为:b->e->g->j,最短距离为:6
b到k的最短路径为:b->e->a->k,最短距离为:6
b到l的最短路径为:b->e->a->k->l,最短距离为:9
发布了11 篇原创文章 · 获赞 0 · 访问量 68

猜你喜欢

转载自blog.csdn.net/yan17iiiiii/article/details/102761112