列表

详情


NC26257. 小雨坐地铁

描述

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

输入描述

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

输出描述

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

示例1

输入:

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

输出:

7

说明:

坐 1 号线:花费 2;

1 \rightarrow 3:花费 2;

换乘 2 号线:花费 2;

3 \rightarrow 4:花费 1;

所以最小总花费为 7 。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 65ms, 内存消耗: 11756K, 提交时间: 2020-04-21 20:22:17

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e6+10,M=2e6+10;
int n,m,s,t,d[N],a[N],vis[N];
int head[N],nex[M],to[M],w[M],tot;
inline void add(int a,int b,int c){to[++tot]=b; nex[tot]=head[a]; w[tot]=c; head[a]=tot;}
void Dijkstra(){
	priority_queue<pair<int,int> > q; q.push({0,s}); memset(d,0x3f,sizeof d); d[s]=0;
	while(q.size()){
		int u=q.top().second;	q.pop();
		if(vis[u])	continue;	vis[u]=0;
		for(int i=head[u];i;i=nex[i])	if(d[to[i]]>d[u]+w[i]){
			d[to[i]]=d[u]+w[i];	q.push({-d[to[i]],to[i]});
		}
	}
}
signed main(){
	cin>>n>>m>>s>>t;
	for(int i=1,x,y,z;i<=m;i++){
		cin>>x>>y>>z;
		for(int j=1;j<=z;j++)	scanf("%d",&a[j]),add(a[j],a[j]+i*n,x),add(a[j]+i*n,a[j],0);
		for(int j=1;j<z;j++)	add(i*n+a[j],i*n+a[j+1],y),add(i*n+a[j+1],i*n+a[j],y);
	}
	Dijkstra();	if(d[t]>=0x3f3f3f3f)	d[t]=-1;
	cout<<d[t];
	return 0;
}

C++ 解法, 执行用时: 138ms, 内存消耗: 4404K, 提交时间: 2022-05-26 08:33:17

#include <bits/stdc++.h>
using namespace std;
constexpr int N = 1e3 + 10;
int n, m, s, t;
int c[N], e[N][N], dis[N];
bool vis[N];
int main(){
	memset(dis, 0x3f, sizeof dis);
	memset(e, 0x3f, sizeof e);
	cin >> n >> m >> s >> t;
	for (int i = 0, x, y, z; i < m; ++i){
		cin >> x >> y >> z;
		for (int j = 0; j < z; ++j){
			cin >> c[j];
			for (int k = j - 1; k >= 0; k--)
				e[c[k]][c[j]] = e[c[j]][c[k]] = min(e[c[j]][c[k]], x + (j - k) * y);
		}
	}
	dis[s] = 0;
	for (int i = 0, u = -1; i < n; ++i, u = -1){
		for (int j = 1; j <= n; ++j)
			if (!vis[j] && (u == -1 || dis[j] < dis[u])) u = j;
		vis[u] = 1;
		for (int j = 1; j <= n; ++j) dis[j] = min(dis[j], dis[u] + e[u][j]);
	}
	if (dis[t] == 0x3f3f3f3f) cout << -1;
	else cout << dis[t];
	return 0;
}

上一题