题意:构建一个有权图,求图中任意两点的最短路径。如图所示,输入两个顶点求他们的最短路径。
思路:选取一个顶点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 <stdio.h>
#include <iostream>
#include <string.h>
#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