最短路径算法主要有两种解决方式:
1、单源的迪杰斯特拉算法:
一个点对所有的点。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法是很有
代表性的最短路径算法
算法详情:
a.初始时,S只包含源点,即S={v},v的距离为0。U包含除v外的其他顶点,即:U={其余顶点},若v与U中顶点u有边,则<u,v>正常有权值,若u不是v的出边邻接点,则<u,v>权值为∞。
b.从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。
c.以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。
d.重复步骤b和c直到所有顶点都包含在S中
double f(int m) {
double dis[500];
bool book[500] = {0};
fill(dis, dis + 500, inf);
for (int i = 0; i < 500; i++) dis[i] = inf;
dis[m] = 0;
for (int i = 1; i <= n * 4 - 1; i++) {
int minn = inf, u = -1;
for (int j = 1; j <= n * 4; j++) {
if (book[j] == false && dis[j] < minn) {
minn = dis[j];
u = j;
}
}
if (u == -1) break;
book[u] = true;
for (int k = 1; k <= n * 4; k++) {
if (e[u][k] < inf && dis[k] > e[u][k] + dis[u]) {
dis[k] = e[u][k] + dis[u];
}
}
}
首先是一个点,对于所有点(n-1)寻找最短路径,其次在找是否存在其他第三方,存在(e[u][k] < inf && dis[k] > e[u][k] + dis[u])的现象,有责替换最短路径
在不断循环直到所有点
2、多源floyd算法
解决任意两点间的最短路径的一种算法
Floyd算法是一个经典的动态规划算法。首先我们的目标是寻找从点i到点j的最短路径。从动态规划的角度看问题,我们需要为这个目标重新做一个诠释(这个诠释正是动态规划最富创造力的精华所在)
算法详情:
从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。
for (int i = 0; i < n * 4; i++)
for (int j = 0; j < n * 4; j++)
pri[i][j] = pri[j][i] = getp(i, j);
for (int i = 0; i < n * 4; i++)
for (int j = 0; j < n * 4; j++) {
if (i == j) continue;
for (int k = 0; k < n * 4; k++) {
if (j == k || i == k) continue;
pri[i][j] = pri[j][i] = min(pri[i][j], pri[i][k] + pri[j][k]);
}
}
3、问题描述
又到暑假了,住在城市 A 的 Car 想和朋友一起去城市 B 旅游。她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第 i 个城市中高速铁路的单位里程价格为 Ti,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为 t。
那么 Car 应如何安排到城市 B 的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。
找出一条从城市 A 到 B 的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。
2、输入格式
第一行有四个正整数 s,t,A,B。
S 表示城市的个数,t 表示飞机单位里程的价格,A,B 分别为城市 A,B 的序号,(1 <= A,B <= S)。
接下来有 S 行,其中第 i 行均有 7 个正整数 xi1,yi1,xi2,yi2,xi3,yi3,Ti,这当中的 (xi1,yi1),(xi2,yi2),(xi3,yi3) 分别是第 i 个城市中任意三个机场的坐标,Ti 为第 i 个城市高速铁路单位里程的价格。
3、输出格式
一个正整数,表示最小花费,保留一位小数。
4、样例输入
3 10 1 3
1 1 1 3 3 1 30
2 5 7 4 5 2 1
8 6 8 8 11 6 3
5、样例输出
47.6
6、数据规模
0 < S <= 100
#include <bits/stdc++.h>
using namespace std;
#define MAXN 405
#define INF 0x7f7f7f7f
int n, s, t;
double P, p[MAXN], tx[5], ty[5], x[MAXN], y[MAXN], pri[MAXN][MAXN], ans = INF;
double calc(int a, int b, int c) {
if (tx[a] == tx[b] && ty[b] == ty[c] || tx[c] == tx[b] && ty[a] == ty[b]) return -1;
return (ty[a] - ty[b])/(tx[a] - tx[b]) * (ty[b] - ty[c])/(tx[b] - tx[c]);
}
double getp(int a, int b) {
return sqrt((x[a] - x[b]) * (x[a] - x[b]) + (y[a] - y[b]) * (y[a] - y[b])) * (a / 4 == b / 4 ? p[a / 4] : P);
}
int main() {
cin >> n >> P >> s >> t;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= 3; j++)
cin >> tx[j] >> ty[j];
if (calc(1, 2, 3) == -1) {
tx[4] = tx[1] + tx[3] - tx[2];
ty[4] = ty[1] + ty[3] - ty[2];
}
else if (calc(2, 1, 3) == -1) {
tx[4] = tx[2] + tx[3] - tx[1];
ty[4] = ty[2] + ty[3] - ty[1];
}
else {
tx[4] = tx[1] + tx[2] - tx[3];
ty[4] = ty[1] + ty[2] - ty[3];
}
for (int j = 1; j <= 4; j++) {
int o = i * 4 + j - 5;
x[o] = tx[j], y[o] = ty[j];
} cin >> p[i - 1];
}
memset(pri, INF, sizeof(pri));
for (int i = 0; i < n * 4; i++)
for (int j = 0; j < n * 4; j++)
pri[i][j] = pri[j][i] = getp(i, j);
for (int i = 0; i < n * 4; i++)
for (int j = 0; j < n * 4; j++) {
if (i == j) continue;
for (int k = 0; k < n * 4; k++) {
if (j == k || i == k) continue;
pri[i][j] = pri[j][i] = min(pri[i][j], pri[i][k] + pri[j][k]);
}
}
for (int i = 1; i <= 4; i++)
for (int j = 1; j <= 4; j++)
ans = min(ans, pri[s * 4 + i - 5][t * 4 + j - 5]);
cout << fixed << setprecision(1) << ans;
return 0;
}