牛客小白月赛16 J-小雨坐地铁(分层图最短路)

链接:https://ac.nowcoder.com/acm/contest/949/J
来源:牛客网

题目描述

小雨所在的城市一共有 m 条地铁线,分别标号为 1 号线,2 号线,……,m 号线。整个城市一共有 n 个车站,编号为 1∼n。其中坐 i 号线需要花费 ai 的价格,每坐一站就需要多花费 bi 的价格。i 号线有 ci 个车站,而且这 ci 个车站都已知,如果某一站有多条地铁线经过,则可以在这一站换乘到另一条地铁线,并且能多次换乘。现在小雨想从第 s 个车站坐地铁到第 t 个车站,地铁等待时间忽略不计,求最少花费的价格,若不能到达输出 -1 。(地铁是双向的,所以 s 可能大于 t)

输入描述:

第一行输入四个正整数 n,m,s,t,分别表示车站个数,地铁线数,起点站和终点站。
第二行到第 m+1 行,每行前三个数为 ai,bi,ci,分别表示坐 i 号线的价格,i 号线每坐一站多花的价格,i 号线车站个数。接下来 ci 个数,表示 i 号线的每一个车站的编号,单调递增。

输出描述:

共一行,一个数表示最小花费,若不能到达输出 -1 。

示例1
输入

5 2 1 4
2 2 3 1 3 5
2 1 4 2 3 4 5

输出

7

说明

坐 1 号线:花费 2;
1→3:花费 2;
换乘 2 号线:花费 2;
3→4:花费 1;
所以最小总花费为 7 。

备注:

1 ≤ n ≤ 103, 1 ≤ m ≤ 500, 1 ≤ s,t ≤ n,1 ≤ ai,bi≤100 , 1 ≤ ci ≤ n, ∑ ci≤105



分析:

不同的地铁线路属于不同的层次,所以是分层图,但是不同层的图之间有相交,如果两两暴力连图时间复杂度会达到O(n*m2)

这里就要用到虚点,就是在原有分层图的基础上再加一层分层图,里面是1~n 所有点的虚点,用于作为中转站(相当于人在地铁站,但是还没决定做哪一号线路),所有点到其虚点的花费为0,而从虚点到对应点的花费为该点所在地铁线路的初始花费

这样建图的时间复杂度就只有O(n*2m)了,同时在使用最短路算法时,起点s和终点t都选定在其虚点上(不然会有多个s和t,而且需要考虑从某一条地铁线路开始的花费)

对于点的编号,因为一条线路(一层分层图)上至多有n个点,所以不同线路的编号可以依次加上0、n、2n、… 、(m-1)* n,而虚点则加上 m* n。



以下代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<algorithm>
#define PII pair<int,int>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f;
const int MOD=1e9+7;
const int maxn=1e3+50;
const int maxm=500+
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值