最短路径算法

最短路径算法主要有两种解决方式:
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;
 }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值