上学要迟到了

单元最短路径问题

题目链接

以下是无意间看到的一位博主写的这个题目的题解,个人觉得写的非常好!!
一位博主深入透彻的讲解

这同样式那位博主花了很长时间写的博客,可以说注入了极大的心血,把自己的算法理解都写下来了
透彻理解dijkstra+堆优化代码思想

题目描述

牛牛早上起床一看,自己睡过了,赶紧起床准备去学校,他去学校只有两种方式,坐公交车和步行,牛牛去学校是一条直线,这条直线上总共有n个车站,车站之间的距离都是相等的,每个车站只有一种公交车ai,每个公交车只在对应的公交站停车,每个公交车的速度也不一样,第i种公交车过一站的时间需要ti,并且公交车是单向行驶,只能从左到到右,走路可以任意走,然而牛牛自己步行走一站需要的时间为T,恰好牛牛家和学校都在某一个站点,分别为s和t,问最少需要多少时间牛牛才能到学校?

题目分析:这是一个十分好的题目,我觉得主要考点在建图,一种十分巧妙的建图方法,本来是把自己的思路讲清楚一下,但是偶然看到一篇题解,看的豁然开朗,所以就借鉴博主的博客,这个博主讲的十分透彻,能够看出来博主是在用心写博客,用心的博客值得用心呵护。

大致说一下建图的方法,我们只需要建立相邻两点之间的路,其他的可以转移

每种公交车能停车的地方就是单向可达的,就可以在图中表现为有向边。注意一点,我们要存的有向边并非每个车站到其后面所有能停车的车站的有向边,而是与之相邻的可停车站的有向边,比如1 2 2 1 2 1 1 2 1,对于第一个位置的1车而言,我们只需要将其与第四个位置的1车构建一条单向边即可,不需要与第六个位置的1车构建有向边,因为只要构建好相邻可停车站的有向边,可以通过状态的转移自然构建好,这就是Dijkstra算法完成的事,所以你就没必要做了。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int pre[maxn], last[maxn], a[maxn], dis[maxn];
const int inf = 0x3f3f3f3f;
#define pii pair<int, int>
int n, m, s, t, T;
vector<pii> g[maxn];
void dijkstra()
{
    memset(dis, inf, sizeof(dis));
    dis[s] = 0;
    priority_queue<pii, vector<pii>, greater<pii> > q;
    q.push(make_pair(0, s));//队列里面第一个位置存放的是源点到这个点的距离,第二个位置记录的是这个点的信息
    while (!q.empty())
    {
        pii p = q.top();
        q.pop();
        int u = p.second;
        if (dis[u] < p.first)//如果距离本来就小于p.first,那么就不用进行更新操作了
            continue;
        for (int i = 0; i < g[u].size(); ++i)//遍历改点的邻接点
        {
            int v = g[u][i].second, w = g[u][i].first;
            if (dis[v] > dis[u] + w)
            {
                dis[v] = dis[u] + w;
                q.push(make_pair(dis[v], v));
            }
        }
    }
}
int main()
{
    scanf("%d%d%d%d%d", &n, &m, &s, &t, &T);
    for (int i = 1; i <= m; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i <= n; ++i)//建图
    {
        int x;
        scanf("%d", &x);
        if (last[x])//如果这个点不是该公交车的起点,而是中途的会停靠的某点,那么就存入公交车的信息
            g[last[x]].push_back(make_pair(a[x], i));
        last[x] = i;//记录相邻点的位置,不相邻之间的点可以通过转移到达
        //步行建立双向边
        g[i].push_back(make_pair(T, i - 1));
        g[i - 1].push_back(make_pair(T, i));
    }
    dijkstra();
    printf("%d\n", dis[t]);
}
自律是一种人生态度,是一种吃的苦中苦方为人上人的精神,是一种一个人长时间的投资,也是一种,用无尽的孤独换来人前的羡慕和自身的荣耀

我的一位好友,前几天保研清华成功,我的这位朋友,从小学开始就一直优秀,总是年纪前几名,我一直羡慕他每每惊艳的成绩单,但随着长时间的接触,我也了解到了惊艳的背后是刻苦的学习,以及极其自律的他

他很阳光,很朝气,,也十分的帅气,是一个永远的白衬衫少年,也是无数女生心中的初恋,哈哈哈

在此,祝福他,前程似锦!!冲冲冲~

今年我的首赞就是它
在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值