图论最短路算法

图论最短路算法

  • 1.Floyd
  • 2.Dijkstra
  • 3.Bellman-Ford

1.Floyd

	求任意两点之间的最短路

算法的基本思想是:遍历每一个点,让此点作为中转点,然后遍历一个起点,一个终点,看看有没有通过中转点的路径比不通过的还短的,有的话就更新最短路

核心代码:

	
int e[maxn][maxn]; //邻接矩阵
	
//以k为中转点看看 (i->k + k->j) 的路径有没有比直接 i->j 还短的
for (int k = 1; k <= n; k++)
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			if (e[i][k] + e[k][j] < e[i][j])
				e[i][j] = e[i][k] + e[k][j];

Floyd算法与点关系密切

2.Dijkstra

	求一个点到其余各个顶点的最短路。

算法的基本思想是:每次找到离远点最近的一个顶点,然后以该顶点为中心进行拓展,最终得到源点到其余所有点的最短路径

核心代码:

/*以1为源点为例*/
	
//初始化数组dis, dis[i]表示源点到i点的距离
for (int i = 1; i <= n; i++)
	dis[i] = e[1][i];

//book用来看是否被标记
for (int i = 1; i <= n; i++)
	book[i] = 0;
book[1] = 1;

for (int i = 1; i <= n - 1; i++) {

	int min = inf, u = 0;

	//找到此时离源点最近且未被标记的点
	for (int j = 1; j <= n; j++)
		if (book[j] == 0 && dis[j] < min) {
			min = dis[j];
			u = j;
		}

	//标记  源点到此点的最短路已经确定
	book[u] = 1;

	//以目前离源点最近的这个点u做中转 进行遍历更新最短路
	for (int v = 1; v <= n; v++)
		if (e[u][v] < inf && dis[u] + e[u][v] < dis[v])
			dis[v] = dis[u] + e[u][v];
}

Dijkstra算法与点关系密切

3.Bellman-Ford

	求一个点到其余各个顶点的最短路。

算法的基本思想是:遍历每条边,看 (1->u + w) 能不能比 1->v 还小,能的话就更新最短路。因为最短路径上最多有n - 1个边,所以最多n - 1个阶段,每一阶段就是一次遍历松弛

核心代码:

/* 以1为源点为例*/

//初始化dis数组,dis[i]为源点到i点的长度
for (int i = 1; i <= n; i++)
	dis[i] = inf;
dis[1] = 0;

for (int k = 1; k <= n - 1; k++)
	for (int i = 1; i <= m; i++)
		if (dis[u[i]] + w[i] < dis[v[i]])
			dis[v[i]] = dis[u[i]] + w[i];

Bellman-Ford算法与边关系密切

你可能感兴趣的:(图论最短路算法)