#include <iostream>
using namespace std;
#include <stack>//重要
#include <cstring>
const int MaxVnum = 100;//这个是城市的个数,可修改
const int INF = 1e7;//无穷大1000000
int dist[MaxVnum], p[MaxVnum];//最短距离和前驱数组
bool flag[MaxVnum];//这个是集合的标志,如果flag[i]=true,说明顶点i
//已经加入到集合S,否则顶点i属于集合V-S
typedef string VexType;//顶点的数据类型,根据需要定义
typedef int EdgeType;//边上权值的数据类型,若不带权值的图,则为0或1
typedef struct {
VexType Vex[MaxVnum];//顶点数组
EdgeType Edge[MaxVnum][MaxVnum];
int vexnum, edgenum;//顶点数,边数
}AMGraph;
int locatevex(AMGraph G, VexType x)
{
for (int i = 0; i < G.vexnum; i++)
{
if (x == G.Vex[i])
{
return i;
}
}
return -1;
}
void CreateAMGraph(AMGraph& G)
{
int i, j, w;
VexType u, v;
cout << "请输入顶点数: " << endl;
cin >> G.vexnum;
cout << "请输入边数: " << endl;
cin >> G.edgenum;
cout << "请输入顶点信息: " << endl;
for (int i = 0; i < G.vexnum; i++)//初始化邻接矩阵为无穷大
{
for (int j = 0; j < G.vexnum; j++)
{
G.Edge[i][j] = INF;
}
}
cout << "请输入每条边依附的两个顶点及权值: " << endl;
while (G.edgenum--)
{
cin >> u >> v >> w;
i = locatevex(G, u);//查找顶点u的存储下标
j = locatevex(G, v);//查找顶点v的存储下标
if (i!= -1 && j != -1)
{
G.Edge[i][j] = w;//有向图邻接矩阵
}
else {
cout << "输入顶点信息有误!!请重新输入!" << endl;
G.edgenum++;//本次输入不算
}
}
}
//这个是从u开始,求到各个顶点的最短距离及其路径
void Dijkstra(AMGraph G, int u)
{
for (int i = 0; i < G.vexnum; i++)
{
dist[i] = G.Edge[u][i];//初始化原点u到其他各个顶点的最短路径长度
flag[i] = false;
if (dist[i] == INF)
{
p[i] = -1;//原点u到该顶点的路径长度为无穷大,说明顶点i与原点u不相邻
}
else {
p[i] = u;//说明顶点i与原点u相邻,设置顶点i的前驱p[i]=u
}
dist[u] = 0;
flag[u] = true;//初始,集合S中只有一个元素,及原点u
for (int i = 0; i < G.vexnum; i++)
{
int temp = INF, t = u;
for (int j = 0; j < G.vexnum; j++)//在集合V-S中寻找距离原点u最近的顶点t
{
if (!flag[j] && dist[j] < temp)
{
t = j;
temp = dist[j];
}
}
if (t == u)return;//找不到t跳出循环
flag[t] = true;//否则,将t加入集合
for (int j = 0; j < G.vexnum; j++)//更新与t相邻接的顶点到原点的距离
{
if (!flag[j] && G.Edge[t][j] < INF)
{
if (dist[j] > (G.Edge[t][j] + dist[t]))
{
dist[j] = dist[t] + G.Edge[t][j];
p[j] = t;
}
}
}
}
}
}
void findpath(AMGraph G, VexType u)
{
int x;
stack<int> S;
cout << "原点为: " << u << endl;
for (int i = 0; i < G.vexnum; i++)
{
x = p[i];
if (x == -1 && u != G.Vex[i])
{
cout << "原点到其他各点的最短路径为: " << u << "---" << G.Vex[i]
<< " sorry,无路可达" << endl;
continue;
}
while (x != -1)
{
S.push(x);
x = p[x];
}
cout << "原点到其他各顶点的最短路径为: ";
while (!S.empty())
{
cout << G.Vex[S.top()] << "--";
S.pop();
}
cout << G.Vex[i] << " 最短距离为:" << dist[i] << endl;
}
}
int main()
{
AMGraph G;
int st;
VexType u;
CreateAMGraph(G);
cout << "请输入源点的信息:" << endl;
cin >> u;
st = locatevex(G, u);//查找源点u的存储下标
Dijkstra(G, st);
cout << "小明所在的位置:" << u << endl;
for (int i = 0; i < G.vexnum; i++)
{
cout << "小明:" << u << " - " << "要去的位置:" << G.Vex[i];
if (dist[i] == INF)
cout << " sorry,无路可达" << endl;
else
cout << " 最短距离为:" << dist[i] << endl;
}
findpath(G, u);
return 0;
}
Dijkstra算法
最新推荐文章于 2024-06-06 20:23:22 发布