最短路(Floyed、Dijkstra、Bellman-Ford、SPFA)
一、Floyed-Warshall算法
枚举中间点起点终点,对整个图进行松弛操作,就能得到整个图的多源最短路径;



例:POJ2240 Arbitrage
Your job is to write a program that takes a list of currency exchange rates as input and then determines whether arbitrage is possible or not.
Input
Test cases are separated from each other by a blank line. Input is terminated by a value of zero (0) for n.
Output
Sample Input
3
USDollar
BritishPound
FrenchFranc
3
USDollar 0.5 BritishPound
BritishPound 10.0 FrenchFranc
FrenchFranc 0.21 USDollar 3
USDollar
BritishPound
FrenchFranc
6
USDollar 0.5 BritishPound
USDollar 4.9 FrenchFranc
BritishPound 10.0 FrenchFranc
BritishPound 1.99 USDollar
FrenchFranc 0.09 BritishPound
FrenchFranc 0.19 USDollar 0
Sample Output
Case 1: Yes
Case 2: No
Source



#include <iostream>
#include <cstdio>
#include <map>
using namespace std;
const int maxn=35;
int n,m;
map<string,int> N;
double dis[maxn][maxn]; int main()
{
int kase=1;
//freopen("Atext.in","r",stdin);
while(cin >> n,n)
{
string a,b;
double tmp;
bool flag=false;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
dis[i][j]=-1;
for(int i=0;i<n;i++){
cin >> a;
N.insert(make_pair(a,i));
}
cin >> m;
for(int i=0;i<m;i++)
{
cin >> a >> tmp >> b;
dis[N[a]][N[b]]=tmp; //邻接矩阵存边的信息;
}
for(int k=0;k<n;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(i!=j&&j!=k&&k!=i&&dis[i][k]!=-1&&dis[k][j]!=-1)
dis[i][j]=max(dis[i][k]*dis[k][j],dis[i][j]);
/*for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
cout << dis[i][j] << " ";
cout << endl;
}
cout << endl;*/
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(dis[i][j]*dis[j][i]>1)flag=1;
printf("Case %d: %s\n",kase,flag?"Yes":"No");
N.clear();
kase++;
}
return 0;
}
附:Warshall算法的传递闭包



例:POJ2253 Frogger
Description
Unfortunately Fiona's stone is out of his jump range. Therefore Freddy considers to use other stones as intermediate stops and reach her by a sequence of several small jumps.
To execute a given sequence of jumps, a frog's jump range obviously must be at least as long as the longest jump occuring in the sequence.
The frog distance (humans also call it minimax distance) between two stones therefore is defined as the minimum necessary jump range over all possible paths between the two stones.
You are given the coordinates of Freddy's stone, Fiona's stone and all other stones in the lake. Your job is to compute the frog distance between Freddy's and Fiona's stone.
Input
Output
Sample Input
2
0 0
3 4 3
17 4
19 4
18 5 0
Sample Output
Scenario #1
Frog Distance = 5.000 Scenario #2
Frog Distance = 1.414
Source

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn=205;
struct node{
int x,y;
}N[maxn];
int con[maxn][maxn],n;
double G[maxn][maxn];
void floyed() //枚举所有边进行松弛;
{
for(int k=0;k<n;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++) //松弛为最大边的最小值;
G[i][j]=min(G[i][j],max(G[i][k],G[k][j]));
}
int main()
{
int kase=0;
while(~scanf("%d",&n),n)
{
for(int i=0;i<n;i++)
scanf("%d%d",&N[i].x,&N[i].y);
for(int i=0;i<n;i++) //这样对称的邻接矩阵只须计算一半
for(int j=i+1;j<n;j++)
G[i][j]=G[j][i]=(double)sqrt(double(N[i].x-N[j].x)*(N[i].x-N[j].x)+double(N[i].y-N[j].y)*(N[i].y-N[j].y));
floyed();
printf("Scenario #%d\n",++kase);
printf("Frog Distance = %.3lf\n\n",G[0][1]);
}
return 0;
}
二、Dijkstra算法



#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=1005;
const int inf=0x3f3f3f3f;
int n;
struct node{
int x,y;
}N[maxn];
bool vis[maxn];
double G[maxn][maxn],d[maxn]; //邻接矩阵
void Dijkstra()
{
fill(vis,vis+n,false);
fill(d,d+n,inf);
d[0]=0;
while(true)
{
int v=-1;
for(int i=0;i<n;i++)
if(!vis[i]&&(v==-1||d[i]<d[v])) //从尚未使用过的顶点中选取一个最小值;
v=i;
if(v==-1)
break;
vis[v]=true;
for(int i=0;i<n;i++)
d[i]=min(d[i],max(d[v],G[v][i])); //源点到各点的最长边的最小值;
}
}
int main()
{
int kase=0;
while(~scanf("%d",&n),n)
{
for(int i=0;i<n;i++)
scanf("%d%d",&N[i].x,&N[i].y);
for(int i=0;i<n;i++) //这样对称的邻接矩阵只须计算一半
for(int j=i+1;j<n;j++)
G[i][j]=G[j][i]=(double)sqrt(double(N[i].x-N[j].x)*(N[i].x-N[j].x)+double(N[i].y-N[j].y)*(N[i].y-N[j].y));
Dijkstra();
printf("Scenario #%d\n",++kase);
printf("Frog Distance = %.3f\n\n",d[1]);
}
return 0;
}
三、Bellman-Ford算法
四、SPFA算法(Shortest Path Faster Algorithm)
队列优化的bellman-ford;
例:POJ1874 畅通工程续
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
0 1 1
0 2 3
1 2 1
0 2
3 1
0 1 1
1 2
-1
#include <iostream>
#include <queue>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn=205;
const int inf=0x3f3f3f3f;
typedef pair<int,int> p;
vector<p>E[maxn];//邻接表;
int n,m,d[maxn],inq[maxn]; //d[maxn]到源点的最短距离,inq[maxn]在队列里的元素;
void init()
{
for(int i=0;i<n;i++)E[i].clear();
for(int i=0;i<n;i++)inq[i]=0;
for(int i=0;i<n;i++)d[i]=inf;
}
void spfa(int x)
{
queue<int> que;
que.push(x),d[x]=0,inq[x]=1;
while(!que.empty())
{
int now=que.front();
que.pop();
inq[now]=0;
for(int i=0;i<E[now].size();i++)
{
int v=E[now][i].first;
if(d[v]>d[now]+E[now][i].second)
{
d[v]=d[now]+E[now][i].second;
if(inq[v]==0){
inq[v]=1;
que.push(v);
}
}
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
int a,b,c;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
E[a].push_back(p(b,c));
E[b].push_back(p(a,c));
}
scanf("%d%d",&a,&b);
spfa(a);
if(d[b]==inf)
cout << -1 << endl;
else
cout << d[b] << endl;
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=205;
const int inf=0x3f3f3f3f;
int n,m,maze[maxn][maxn]; void floyed()
{
for(int k=0;k<n;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(i!=j&&j!=k&&k!=i)
maze[i][j]=min(maze[i][j],maze[i][k]+maze[k][j]);
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int a,b,c;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(i!=j)
maze[i][j]=inf;
}
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
maze[a][b]=min(c,maze[a][b]);//处理解决重边问题;
maze[b][a]=min(c,maze[b][a]);
}
scanf("%d%d",&a,&b);
floyed();
if(maze[a][b]==inf)
cout << -1 << endl;
else
cout << maze[a][b] <<endl;
}
return 0;
}
//自我整理:最短路径的这三个算法,就像BFS一样;
//spfa:每次把发生更新的点作为当前到该点的最短路径,都入队列视为下一次遍历开始的源点;
//dijkstra:每次只取所有发生更新的点,即所有当前最短路径中里离源点最近的点作为下一次开始的源点,前面的值都视为已确定的最短路径
最短路(Floyed、Dijkstra、Bellman-Ford、SPFA)的更多相关文章
- HDOJ 2544 最短路(最短路径 dijkstra算法,SPFA邻接表实现,floyd算法)
最短路 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- 蓝桥杯 algo_5 最短路 (bellman,SPFA)
问题描述 给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环).请你计算从1号点到其他点的最短路(顶点从1到n编号). 输入格式 第一行两个整数n, m. 接下来的m行,每行有三个 ...
- Til the Cows Come Home 最短路Dijkstra+bellman(普通+优化)
Til the Cows Come Home 最短路Dijkstra+bellman(普通+优化) 贝西在田里,想在农夫约翰叫醒她早上挤奶之前回到谷仓尽可能多地睡一觉.贝西需要她的美梦,所以她想尽快回 ...
- hdoj 2544 最短路【dijkstra or spfa】
最短路 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- 【最短路算法】Dijkstra+heap和SPFA的区别
单源最短路问题(SSSP)常用的算法有Dijkstra,Bellman-Ford,这两个算法进行优化,就有了Dijkstra+heap.SPFA(Shortest Path Faster Algori ...
- ACM/ICPC 之 最短路径-Bellman Ford范例(POJ1556-POJ2240)
两道Bellman Ford解最短路的范例,Bellman Ford只是一种最短路的方法,两道都可以用dijkstra, SPFA做. Bellman Ford解法是将每条边遍历一次,遍历一次所有边可 ...
- poj1860 bellman—ford队列优化 Currency Exchange
Currency Exchange Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 22123 Accepted: 799 ...
- Bellman - Ford 算法解决最短路径问题
Bellman - Ford 算法: 一:基本算法 对于单源最短路径问题,上一篇文章中介绍了 Dijkstra 算法,但是由于 Dijkstra 算法局限于解决非负权的最短路径问题,对于带负权的图就力 ...
- uva 558 - Wormholes(Bellman Ford判断负环)
题目链接:558 - Wormholes 题目大意:给出n和m,表示有n个点,然后给出m条边,然后判断给出的有向图中是否存在负环. 解题思路:利用Bellman Ford算法,若进行第n次松弛时,还能 ...
- 最短路计数——Dijkstra
题目: 给出一个N个顶点M条边的无向无权图,顶点编号为1−N.问从顶点1开始,到其他每个点的最短路有几条. ——传送门 受到题解的启发,用 Dijkstra A掉(手工代码) 思路: 1.无向无权图, ...
随机推荐
- 如何让Macbook Touch Bar 一直显示F1~F12
原始状态 修改过程 系统偏好设置 > 键盘 将Touch Bar Shous 修改为F1, F2 ,etc. 结果
- gitlab-ce安装
# vim /etc/yum.repos.d/gitlab-ce.repo [gitlab-ce] name=Gitlab CE Repository baseurl=https://mirrors. ...
- Bitcask — 日志结构的快速 KV 存储引擎
Bitcask 介绍 Bitcask 是一种高性能的键值存储引擎,基于日志结构和哈希索引来提供高速的读写操作和数据持久性,适用于处理大量写入请求和快速查找键值对的应用场景. 核心概念 Bitcask ...
- opencv-python 4.9.2. 轮廓特征
矩 图像的矩可帮助你计算某些特征,如对象的质心,对象的面积等特征.函数cv.moments()给出了计算的所有矩值的字典. 从这一刻起,你可以提取有用的数据,如面积,质心等.质心由关系给出, $$ C ...
- -O1 -O2 -O3 优化的原理是什么?
一般来说,如果不指定优化标识的话,gcc就会产生可调试代码,每条指令之间将是独立的:可以在指令之间设置断点,使用gdb中的 p命令查看变量的值,改变变量的值等.并且把获取最快的编译速度作为它的目标. ...
- Unity3D中的Attribute详解(二)
上一篇文章我们初步了解了一下Attributes的含义,并且使用系统自带的Attributes写了点代码.在进一步解剖我们的代码之前,我觉得有个概念可能需要巩固一下:什么是元数据? 我们知道C#代码会 ...
- Service Mesh之Istio部署bookinfo
前文我们了解了service mesh.分布式服务治理和istio部署相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/17281541.html:今天我 ...
- yaml-cpp YAML格式处理库的介绍和使用(面向业务编程-文件格式处理)
yaml-cpp YAML格式处理库的介绍和使用(面向业务编程-文件格式处理) YAML格式介绍 YAML的格式介绍,有关ini.json和xml或许很多人已经很了解了,但是关于YAML,还有许多人不 ...
- 升级二进制kubernetes集群
升级二进制kubernetes集群 背景介绍 最近由于时间不足,暂时无法对小版本更新第一时间出新的文档.若需要升级集群版本,可以参考此文档进行操作,每个节点一个一个地更新.大版本更新请各位持续关注我的 ...
- Python 人工智能 5秒钟偷走你的声音
介绍 Python 深度学习AI - 声音克隆.声音模仿,是一个三阶段的深度学习框架,允许从几秒钟的音频中创建语音的数字表示,并用它来调节文本到语音模型,该模型经过培训,可以概括到新的声音. 环境准备 ...