图论-最短路-Dijkstra算法&Floyd算 c++

最短路径解决了求解一个图中两顶点之间最短的路径问题。其中Dijkstra算法应用贪心法求解单源点到其余各点的最短路径问题;而Floyd算法则解决了图中任意两点间的最短路径问题。

/*Dijkstra算法
时间复杂度O(n^2)
1.当前源点到任意点路径长度集合dist中的最短路径(v,vk)必为源点v到vk的最短路径,
因为源点v再经由其他点到vk必定比当前路径长度长
2.取min{(v,vi)当前长度,(v,vk)当前长度+(vk,vi)长度}为当前长度,反证法可知其贪心正确性
3.更新后将vk标记,下次不再查询
4.重复上述步骤直到每个点都查询一遍*/
struct vertex
{
	int v;
	string vex;
};
vertex Vertex[MAX];
int Groph[MAX][MAX];
void Dijkstra(int v, int n)
{
	vector dist;//存储当前源点到任意点最短路长度
	vector path;//存储当前源点到任意点最短路径
	vector s;//存储源点与已经生成的终点的集合
	for (int i = 0; i < n; ++i)
	{
		dist.push_back(Groph[v][i]);
		if (dist[i] == INF)
			path.push_back(Vertex[v].vex + Vertex[i].vex);
		else
			path.push_back("");
	}
	s.push_back(v);
	dist[v] = 0;
	int num = 1;

	while (num < n)
	{
		int k = 0;
		for (int i = 0; i < n; ++i)
			if (dist[i] != 0 && dist[i] < dist[k])//找dist中的最小值k
				k = i;
		cout << dist[k] << " " << path[k] << endl;
		s.push_back(k);//加入集合s
		++num;
		for (int i = 0; i < n; ++i)
		{
			if (dist[i]>dist[k]+Groph[k][i])//若源点经由k到其他点路径长度比当前路径长度小则修改dist和path
			{
				dist[i] = dist[k] + Groph[k][i];
				path[i] = path[k] + Vertex[i].vex;
			}
		}
		dist[k] = 0;//标记为已完成终点

	}

}
/*Floyd算法
时间复杂度O(n^3)
*/
struct vertex
{
	int v;
	string vex;
};
vertex Vertex[MAX];
int Groph[MAX][MAX];
void Floyd(int n)
{
	int dist[MAX][MAX];//distk[i][j]=min{dist(k-1)[i][j], dist(k-1)[i][k]+dist(k-1)[k][j]},0<=k<=n-1
	string path[MAX][MAX];
	for (int i = 0; i < n; ++i)//初始化dist和path
		for (int j = 0; j < n; ++j)
		{
			dist[i][j] = Groph[i][j];
			if (dist[i][j] != INF)
				path[i][j] = Vertex[i].vex + Vertex[j].vex;
			else
				path[i][j] = "";
		}
	for (int k = 0; k < n; ++k)//进行n次迭代
		for (int i = 0; i < n; ++i)//顶点i,j之间是否经过k点
			for (int j = 0; j < n; ++j)
				if (dist[i][k] + dist[k][j] < dist[i][j])
				{
					dist[i][j] = dist[i][k] + dist[k][j];
					path[i][j] = path[i][k] + path[k][j];
				}

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			cout << path[i][j] << dist[i][j] << endl;
}



你可能感兴趣的:(数据结构/算法)