上学要迟到了【最短路转化】

题意

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

(n,m≤1×10^5,1≤s,t≤n,1≤T≤1×10^4,1≤t_i≤1×10^4,1≤a_i≤m)

链接:https://ac.nowcoder.com/acm/contest/7412/H

分析

一开始想怎么贪心,(DP),但都没想到怎么做,看了题解说转化为最短路,顿时醒悟,确实符合最短路的模型啊。

代码

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef pair<int,int>pii;
const int inf=0x3f3f3f3f;
const int N=1e5+5;
priority_queue<pii,vector<pii>,greater<pii> >que;
int ti[N],a[N],last[N],dis[N];
vector<pii>pic[N];
void dij(int s,int t,int n)
{
    for(int i=1;i<=n;i++) dis[i]=inf;
    while(!que.empty()) que.pop();
    dis[s]=0;
    que.push(make_pair(0,s));
    while(!que.empty())
    {
        pii now=que.top();
        que.pop();
        if(dis[now.second]<now.first) continue;
        for(int i=0;i<pic[now.second].size();i++)
        {
            pii tmp=pic[now.second][i];
            if(dis[now.second]+tmp.first<dis[tmp.second])
            {
                dis[tmp.second]=dis[now.second]+tmp.first;
                que.push(make_pair(dis[tmp.second],tmp.second));
            }
        }
    }
}
int main()
{
    int n,m,s,t,T;
    scanf("%d%d%d%d%d",&n,&m,&s,&t,&T);
    for(int i=1;i<=m;i++) scanf("%d",&ti[i]);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
    {
        if(last[a[i]]>0)
            pic[last[a[i]]].pb(make_pair(ti[a[i]],i));
        last[a[i]]=i;
    }
    for(int i=1;i<n;i++)
    {
        pic[i].pb(make_pair(T,i+1));
        pic[i+1].pb(make_pair(T,i));
    }
    dij(s,t,n);
    printf("%d
",dis[t]);
    return 0;
}

原文地址:https://www.cnblogs.com/1024-xzx/p/13769391.html