一.弗洛伊德算法
用途:用来求解多源点最短路径问题。
思想:Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法。
主要步骤:
1)初始化:使用邻接矩阵初始化dist数组
2)依次考察每个顶点:在当前dist数组中依次加入各个顶点,考察是否对最短路径产生影响。如果路径变短,则更新dist数组和path数组。
时间复杂度:
二.实战演练
1.题目描述:
小明喜欢观景,于是今天他来到了蓝桥公园。
已知公园有N个景点,景点和景点之间一共有M条道路。小明有Q个观景计划,每个计划包含一个起点st和一个终点ed,表示他想从st去到ed。但是小明的体力有限,对于每个计划他想走最少的路完成,你可以帮帮他吗?
输入描述:
输入第一行包含三个正整数:N,M,Q
第2到第M+1行每行包含三个正整数u,v,w,表示之间存在一条距离为w的路。
第M+2到第M+Q-1行每行包含两个正整数st,ed。
输出描述:
输出共Q行,对应输入数据中的查询。
若无法从st到ed,则输出-1.
2.思路:
memset是一个初始化函数,作用是将某一块内存全部设置为指定的值。
void *memset(void *s, int c, size_t n);
- s指向要填充的内存块。
- c是要被设置的值。
- n是要被设置该值的字符数。
- 返回类型是一个指向存储区s的指针。
3.代码实现:
#include <iostream>
#include <cstring>
using namespace std;//有n个顶点,m条边的无向图
long long dist[405][405],n,m,q,u,v,w;int main(int argc, const char * argv[]) {ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n>>m>>q;memset(dist, -1, sizeof(dist));for(int i=1;i<=n;i++){dist[i][i]=0;}for(int i=0;i<m;i++){cin>>u>>v>>w;if(dist[u][v]!=-1)dist[u][v]=dist[v][u]=min(w,dist[u][v]);//防止出现重复边elsedist[u][v]=dist[v][u]=w;}//floydfor(int i=1;i<=n;i++)for(int j=1;j<=n;j++)for(int k=1;k<=n;k++)if(dist[j][i]!=-1&&dist[i][k]!=-1){if(dist[j][k]==-1||dist[j][k]>dist[j][i]+dist[i][k]){dist[j][k]=dist[j][i]+dist[i][k];}}int st,ed;for(int i=0;i<q;i++){cin>>st>>ed;cout<<dist[st][ed]<<'\n';}return 0;
}