ナレーション
今日、私はついに有名な貪欲なアルゴリズム、ダイクストラアルゴリズムについて書きました、そして私は少し興奮していました。
-
小明のストーリー
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
*/