图--最短路径算法(Dijkska)

Dijkstra算法

Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。注意该算法要求图中不存在负权边。

问题描述: 在无向图 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径。(单源最短路径)

原理

Dijkstra是贪心算法(每次都想取目前的最优),从出发点开始,它每次从不在最短路径树上的点集合中寻找最近的点,将其加入最短路径树,并从该点更新起点到它的邻接边的距离,直到遍历完所有点或遇到目的地。

选取A作为起点,path为到达该节点的路径的前一个节点的下标,dist表示起点到该节点的距离,

visited表示该节点是否被访问,将dist初始化为起点到该节点的权值,不可达的表示为∞,将path对应dist不为无穷的更新为起点,其余为-1

从visited中未访问过的节点中选取dist最小的节点2

将2其标记为已访问,然后将2可到达的节点的dist值进行更新,如果dist[2]+arc[2][i]      (将2作为中继站)<dist[i],则进行更新,并将path[i]修改为2,重复以上步骤

想要找到起点到某点的最短路径,则从path中找到该点对应的path[i],再查找下标path[i]对应的值,直到下标与值相等

const int MAXSIZE = 100;
#define inf 0x3f3f3f3f

void Disjkstra(int start)
{
	
	int dist[MAXSIZE];
	int path[MAXSIZE];
	bool visited[MAXSIZE] = { 0 };
    //初始化
	visited[start] = 1;//1表示v已在集合中
	for (int i = 0; i < vertexNum; i++)
	{
		dist[i] = arc[start][i];
		if (dist[i] != inf)
			path[i] = start;
		else path[i] = -1;
	}

	for (int i = 0; i < vertexNum; i++)
	{
		int min = inf;
		int k = 1;
		int j = 0;
        //查找未访问集合中最小dist对应的下标
		while (j < vertexNum)
		{
			if (visited[j] == 0 && dist[j] < min)
			{
				min = dist[j];
				k = j;
			}
			j++;
		}
		visited[k] = 1;
        //更新dist和path
		for (int i = 0; i < vertexNum; i++)
		{
			if (visited[i] == 0 && (dist[i] > min + arc[k][i]))
			{
				dist[i] = min + arc[k][i];
				path[i] = k;
			}
		}
	}
	
    for (int i = 0; i < vertexNum; i++)
	{
		if (i == start)
			continue;

		cout << "从" << vertex[start] << "到" << vertex[i] << "的最短路径为:" ;
		int temp = i;
		stack st;
		st.push(temp);
		while (temp != start)
		{
			temp = path[temp];
			st.push(temp);
		}
		while (!st.empty())
		{
			int x = st.top();
            st.pop();
			cout << vertex[x] << " ";
		}
		cout << "路径长度为" << dist[i];
		cout << endl;
	}

}

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值