下面来讲一下Floyd算法。
Floyd算法很容易理解,最核心的部分就是找中间点。找到一个中间点,看是直接从起点到终点快还是从起点先到中间点再到终点快。理解思路后,我们就可以看一下其代码实现:
void Floyd(){
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
f[i][j]=min(f[i][j],f[i][l]+f[l][j]);
}
}
}
}
非常简单,执行完该函数之后图中任意两点之间的距离都已经被求出。该算法适用于稠密图,速度快,代码简单。
下面就可以做道题了:
Floyd求最短路
时间限制:1秒 内存限制:128M
题目描述
给定一个n个点m条边的有向图,图中可能存在重边和自环,边权可能为负数。
再给定k个询问,每个询问包含两个整数x和y:表示查询从点x到点y的最短距离,如果路径不存在,则输出”impossible”。
数据保证图中不存在负权回路。输入描述
第一行包含三个整数n,m,k
接下来m行,每行包含三个整数x,y,Z:表示存在一条从点x到点y的有向边,边长为z。
接下来k行,每行包含两个整数x,y,表示询问点x到点y的最短距离。输出描述
共k行, 每行输出一个整数, 表示询问的结果, 若询问两点间不存在路径, 则输出”impossible”。
样例
输入
3 3 2 1 2 1 2 3 2 1 3 1 2 1 1 3输出
impossible 1提示
1≤n<=200,
1<=k<=n^2
1≤m≤20000
图中涉及边长绝对值均不超过10000。
这是一道Floyd算法的模板题,我们直接来看代码:
#include<iostream>
#include<cstring>
using namespace std;
int n,m,k;
int x,y,z;
int f[210][210];
void Floyd(){
for(int l=1;l<=n;l++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
f[i][j]=min(f[i][j],f[i][l]+f[l][j]);
}
}
}
}
int main(){
memset(f,0x3f,sizeof(f));
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
f[i][i]=0;
}
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
f[x][y]=min(f[x][y],z); //有重边
}
Floyd();
for(int i=1;i<=k;i++){
cin>>x>>y;
if(f[x][y]>=0x3f3f3f3f/2){
cout<<"impossible"<<endl;
}
else{
cout<<f[x][y]<<endl;
}
}
return 0;
}
注意事项都在代码中,自行观看即可。
感谢观看!