最短路,Floyd | 洛谷 P1346 电车

题目传送门

题意

有一个 N 个点的有向图,每个点都连接着若干条边(可能有环)。每个点默认只能指向输入的第一个点,去其他点就需要将路程 +1
请写一个程序,计算点 A 到点 B 的最短路径。若无法从 A 前往 B,输出 1

分析

Floyd 算法是用来求图中任意两个结点之间的最短路的。实现方法如下:

  • 定义
    我们定义一个数组 dis[x][y],表示 xy 的最短路长度。
  • 初始化

    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;
}
posted @   心灵震荡  阅读(44)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 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】
点击右上角即可分享
微信分享提示