ダイクストラアルゴリズムの最短経路

ナレーション

今日、私はついに有名な貪欲なアルゴリズム、ダイクストラアルゴリズムについて書きました、そして私は少し興奮していました。

  • 小明のストーリー

    Dijstraアルゴリズムは多くの人にとって難しいように見えますが、あまり理解できませんが、それは何の意味もありません!
    たとえば、Xiao Mingは科学技術大学から博物館まで自分で運転したいと考えています。XiaoMingは、石油価格の高騰と貧困層の貧困を考慮に入れると、それほど頑張って歩き回ることができないため、最短の道を探して、ディックのように慎重に計画を始めました。それらの不要な費用を終わらせるため。地図を取り出し、さまざまなルートを慎重に比較して美術館に向かいますが、複雑な道路網は暁明を驚かせます。しばらくの間、最も経済的なルートを見つけることができず、あなたの心は非常にイライラします。現時点では、暁明がポケットから取り出します。そこにバイ将軍が息を呑み、突然光が彼の心から閃き、そして最短の道を素早く見つけた。
    ここに画像の説明を挿入

  • Xiao Mingはどのようにしてそれを達成しましたか?
    Xiao Mingは、最初に科学技術大学に最も近いランドマークを見つけ、次にこのランドマークを出発点として使用して、目的地が見つかるまで、次の最も近いランドマークを段階的に見つけることができるかどうか疑問に思いました。毎回検出される距離が最も近いため、出発地から目的地までの累積距離も最も近くなります。興奮した小明が白将の未完成の半分を地面に投げ、数回彼の足でこすり、最短の道を探し始め、すぐに理想的なルートを見つけました。

  • Xiao Mingの素晴らしい生活、
    コンピュータの背景、Xiao Mingは帰国後、ビジネスチャンスをすばやく発見しました。彼の創意工夫により、地図ソフトウェアを開発し、多額のお金を稼ぎ、そのお金を使って中国最大の単一の出会い系プラットフォームであるCSDNに投資しました、CSDNのボスになって、幸せな生活を送ってください。

コードの実装

	/*
	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
	*/

おすすめ

転載: blog.csdn.net/m0_43456002/article/details/104382960
おすすめ