Dijkstra algorithm shortest path

Narrate

Today I finally wrote about the famous greedy algorithm- Dijkstra algorithm , and I was a little excited.

  • Xiao Ming's story

    The Dijstra algorithm looks difficult to many people, and it is not very understandable, but it is nothing!
    For example, Xiao Ming wants to drive from the University of Science and Technology to a museum by himself. Taking into account the rising oil prices and impoverished pockets, Xiao Ming can’t be so headstrong and take a walk-and-go trip, so Xiao Ming began to plan carefully like a dick, looking for the shortest path. To end those unnecessary expenses. You take out the map and carefully compare the various routes to the museum, but the complicated road network dazzles Xiao Ming. You will not find the most economical route for a while, and your heart is very irritable. At this moment, Xiao Ming takes out his pocket. General Bai in the room took a hard breath, suddenly a light flashed out of his mind, and quickly found the shortest path.
    Insert picture description here

  • How did Xiao Ming achieve it?
    Xiao Ming wondered if I could find the landmark closest to the University of Science and Technology first, and then use this landmark as a starting point to find the next closest landmark, step by step, until I found the destination. Because the distance found each time is the closest, the cumulative distance from the origin to the destination is also the closest. Sure enough, it was a good idea. The excited Xiao Ming threw the unfinished half of General Bai on the ground, rubbed a few times with his feet, and started looking for the shortest path, and soon found the ideal route.

  • Xiao Ming’s splendid life, a
    computer background, Xiao Ming quickly discovered business opportunities after returning. Through his ingenuity, he developed a map software, made a lot of money, and used the money to invest in the largest single dating platform in China—CSDN , Become the boss of CSDN and lead a happy life.

Code implementation :

	/*
	Dijkstra的思路就是:
	找到与源点权值最小的边,然后再此边找到到其他顶点的最小的边,依次类推,每次找到的都是最小的边
	最后所得的最短路径长度就是各最小边的和
	*/
	
	#include<iostream>
	#include<string>
	#include<stack>
	using namespace std;
	
	#define OK 1
	#define ERROR 0
	#define MAXint 32767 //表示无穷大
	#define MVNum 100	//最大顶点数
	
	//邻接矩阵的结构
	typedef struct
	{
    
    
		string vexs[MVNum];//顶点表
		int arcs[MVNum][MVNum];//邻接矩阵,也就是表示边的权值
		int vexnum, arcnum;//图的顶点数和边的个数
	}AMGraph;
	//邻接矩阵的结构
	
	//Dijstra结构
	bool S[MVNum] = {
    
     false };//记录从源点到终点是否已被确定最短路径长度
	int Path[MVNum] = {
    
     -1 };//记录终点的直接前驱序号
	int D[MVNum];//记录最短路径长度
	//Dijstra结构
	
	
	//查询结点位置
	int Locate(AMGraph G, string v)
	{
    
    
		for (int i = 0; i < G.vexnum; i++)
		{
    
    
			if (G.vexs[i] == v)
			{
    
    
				return i;
			}
		}
		return -1;
	}
	//查询结点位置
	
	//创建邻接矩阵
	int CreateUDN(AMGraph& G)//无向图的构造
	{
    
    
		cout << "请输入图的顶点数和边数:";
		cin >> G.vexnum >> G.arcnum;
		cout << "请输入各点的信息:";
		for (int i = 0; i < G.vexnum; i++)
		{
    
    
			cin >> G.vexs[i];
		}
		for (int i = 0; i < G.vexnum; i++)//初始化边的权值为MAXINT
		{
    
    
			for (int j = 0; j < G.vexnum; j++)
			{
    
    
				G.arcs[i][j] = MAXint;
			}
		}
		cout << "各边的顶点信息和权值:";
		for (int k = 0; k < G.arcnum; k++)//构造邻接矩阵
		{
    
    
			string v1, v2;
			int w;//边的两个顶点以及权值
			cin >> v1 >> v2 >> w;
			int i = Locate(G, v1);//找到点的位置
			int j = Locate(G, v2);
			G.arcs[i][j] = w;//赋予权值
			//G.arcs[j][i] = G.arcs[i][j];
		}
		return OK;
	}
	//创建邻接矩阵
	
	
	//Dijksta
	void ShortestPath_DIJ(AMGraph G, int v)
	{
    
    
		int n = G.vexnum;//图的节点的数量
		for (int i = 0; i < n; i++)
		{
    
    
			D[i] = G.arcs[v][i];
			if (D[i] < MAXint)
			{
    
    
				Path[i] = v;
			}
			else
			{
    
    
				Path[i] = -1;
			}
		}
		S[v] = true;//初始化v已有最短路径
		D[v] = 0;//最短路径为0
		for (int i = 1; i < n; i++)
		{
    
    
			int min = MAXint;
			for (int j = 0; j < n; j++)//找到与v邻接的边的权值最小的
			{
    
    
				if (!S[j] && D[j] < min)
				{
    
    
					v = j;
					min = D[j];
				}
			}
			S[v] = true;//找到最短路径
			for (int k = 0; k < n; k++)//更新从v出发到各顶点的最短路径长度
			{
    
    
				if (!S[k] && (D[v] + G.arcs[v][k]) < D[k])
				{
    
    
					D[k] = D[v] + G.arcs[v][k];//更新最短路径长度
					Path[k] = v;//更改k的前驱为v
				}
			}
		}
	}
	//Dijksta
	
	//显示最短路径
	void ShowShortTest(AMGraph G, string v)
	{
    
    
		int s = Locate(G,v);//定位
		ShortestPath_DIJ(G, s);
		for (int i = 0; i < G.vexnum; i++)
		{
    
    
			stack<string> sta;//引入栈
			if (i != s && Path[i] != -1)
			{
    
    
				sta.push(G.vexs[i]);
				int path = Path[i];
				while (path != -1)
				{
    
    
					sta.push(G.vexs[path]);
					path = Path[path];
				}
			}
			if (!sta.empty())
			{
    
    
				cout << sta.top();
				sta.pop();
			}
			while (!sta.empty())
			{
    
    
				cout << "->";
				cout << sta.top();
				sta.pop();
			}
	
			if (i != s && Path[i] != -1)
			{
    
    
				cout << " 最短路径长度为:" << D[i];
				cout << endl;
			}
		}
	
	}
	//显示最短路径
	
	int main()
	{
    
    
		AMGraph G;
		CreateUDN(G);
		string v;
		cout << "请输入起点:";
		cin >> v;
		ShowShortTest(G, v);
		return 0;
	}
	/*
	v0 v1 v2 v3 v4 v5
	各边的顶点信息和权值:v1 v2 5 v2 v3 50 v0 v2 10 v0 v4 30 v4 v3 20 v3 v5 10 v0 v5 100 v4 v5 60
	*/

Guess you like

Origin blog.csdn.net/m0_43456002/article/details/104382960