最短路,Floyd | 洛谷 P1346 电车
题意
有一个 N 个点的有向图,每个点都连接着若干条边(可能有环)。每个点默认只能指向输入的第一个点,去其他点就需要将路程 +1。
请写一个程序,计算点 A 到点 B 的最短路径。若无法从 A 前往 B,输出 −1。
分析
Floyd 算法是用来求图中任意两个结点之间的最短路的。实现方法如下:
- 定义
我们定义一个数组dis[x][y]
,表示 x 到 y 的最短路长度。 - 初始化dis[u][v]={wu,v(u,v)∈E0u=vinfOtherwise.
- 转移
每次找一个中转点 k,再对每一组 x,y 的最短路进行松弛操作。
dis[x][y] = min(dis[x][y], dis[x][k] + dis[k][y])
- 复杂度
时间复杂度为 O(n3),空间复杂度为 O(n2)。
本题可以用 Floyd 算法求解。过程如下:
- 初始化 dis 数组。
- 读入存图(邻接矩阵),注意在此题中,只有每个点到输入的第一个点的 dis 值才为 0,其它出边为 1。
- 跑一遍 Floyd 算法,求出每两个点之间的最短路径。
- 输出答案,注意若求得答案为 inf,则说明没有路径,要按题意输出 −1。
代码
#include<bits/stdc++.h>
using namespace std;
const int inf = 1e9;
int n, s, t, k, x, dis[105][105];
inline void init()
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
dis[i][j] = inf, dis[i][i] = 0;
}
inline void Floyd()
{
for(int k = 1; k <= n; k++)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
return;
}
int main()
{
ios :: sync_with_stdio(false);
cin >> n >> s >> t;
init();
for(int i = 1; i <= n; i++)
{
cin >> k;
for(int j = 1; j <= k; j++)
{
cin >> x;
dis[i][x] = !(j == 1);
}
}
Floyd();
cout << (dis[s][t] == inf ? -1 : dis[s][t]);
return 0;
}
望穿寂夜晨曦至,雄鹰展翅图九天。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】