Dijkstra算法

#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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值