最短路问题(Bellman-Ford算法)

题意:构建一个有权图,求图中任意两点的最短路径。如图所示,输入两个顶点求他们的最短路径。

最短路问题(Bellman-Ford算法)_第1张图片

思路:选取一个顶点v作为起点,用数组d[i],表示到该顶点到i顶点的最短路径,那么该点的最短路径的d[v]=0为0.。然后从改点出发更新该点附近的最短路径,需要注意的是,每次更新完的d[i]值并不一定就是最短路径,因为可能存在其他路径更短,例如从B到E的最短路径为A->C->D->F->E,d[4]=11。但是从B点开始更新时d[4]=12.

所以需要进行多次更新,将前面不够准确的值“覆盖”.当无法更新时结束。具体大家可以自己演示体会。

1)将起点d[v]=0;


2)遍历所有边,把最短距离确定的顶点所连接的另一个所有顶点dp[to]=min(d[to],d[from]+e.cost),最短距离更新


3)重复2)直到无法更新。

代码如下:

#include 
#include 
#include 
#define MAX 1000
#define INF 100000
using namespace std;

typedef struct edge
{
	int from, to, cost;
}edge;
edge es[MAX];
int d[MAX];
int V, E;

void shortest_path(int s) 
{
	for (int i = 0; i < V; i++)
		d[i] = INF;
	d[s] = 0;
	while (true) 
	{
		bool updata = false;
		for (int i = 0; i < 2*E; i++) 
		{
			edge e = es[i];
			if (d[e.from] != INF&&d[e.to]>d[e.from] + e.cost) 
			{
				d[e.to] = d[e.from] + e.cost;
				updata = true;
			}
		}
		if (!updata) break;
	}
}

void solve(int from,int to) 
{
	shortest_path(from);
	printf("%d\n", d[to]);
	return;
}

int main() 
{
	cin >> V >> E;
	for (int i = 0; i < 2*E; i++) 
	{
		cin >> es[i].from >> es[i].to >> es[i].cost;
	}
	int from, to;
	cin >> from >> to;
	solve(from, to);
	return 0;
}

样例输入

7 10
0 1 2
0 2 5
1 0 2
1 2 4
1 3 6
1 4 10
2 0 5
2 1 4
2 3 2
3 1 6
3 2 2
3 5 1
4 1 10
4 5 3
4 6 5
5 3 1
5 4 3
5 6 9
6 4 5
6 5 9
0 6

样例输出

16


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