小雨坐地铁

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

题目描述
小雨所在的城市一共有 mm 条地铁线,分别标号为 1 号线,2 号线,……,m 号线。整个城市一共有 nn 个车站,编号为 1 \sim n1∼n 。其中坐 i 号线需要花费 a_ia
i

的价格,每坐一站就需要多花费 b_ib
i

的价格。i 号线有 c_ic
i

个车站,而且这 c_ic
i

个车站都已知,如果某一站有多条地铁线经过,则可以在这一站换乘到另一条地铁线,并且能多次换乘。现在小雨想从第 ss 个车站坐地铁到第 tt 个车站,地铁等待时间忽略不计,求最少花费的价格,若不能到达输出 -1 。(地铁是双向的,所以 ss 可能大于 tt)
输入描述:
第一行输入四个正整数 n,m,s,tn,m,s,t,分别表示车站个数,地铁线数,起点站和终点站。
第二行到第 m + 1m+1 行,每行前三个数为 a_i,b_i,c_ia
i

,b
i

,c
i

,分别表示坐 i 号线的价格,i 号线每坐一站多花的价格,i 号线车站个数。接下来 c_ic
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 31→3:花费 2;

换乘 2 号线:花费 2;

3 \rightarrow 43→4:花费 1;

所以最小总花费为 7 。
备注:
1 \leq n \leq 10^3, 1 \leq m \leq 500,1 \leq s,t \leq n1≤n≤10
3
,1≤m≤500,1≤s,t≤n

1 \leq a_i,b_i \leq 100,1 \leq c_i \leq n,\sum\limits_{i = 1}^m c_i \leq 10^51≤a
i

,b
i

≤100,1≤c
i

≤n,
i=1

m

c
i

≤10
5

就是给每一个站建立一个虚拟的点,这个点到虚拟点花钱,虚拟点到他不花钱

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <bits/stdc++.h> 

using namespace std;

#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
//#define x first
//#define y second

int dx[4] = {
    
    0, 1, 0, -1};
int dy[4] = {
    
    1, 0, -1, 0}; 

//typedef __int128 INT;
typedef pair<int, int> PII;
typedef unsigned long long ULL;

inline int read(int out = 0)
{
    
    
    char c;
    while((c=getchar()) < 48 || c > 57);
    while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
    return out; 
}

const int N = 1e5 + 100;
const int M = 1e6;
const int mod = 2333;
const int PP = 13331;
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const double PI = acos(-1);

int n, m, s, t;

int h[M], e[M], ne[M], w[M], idx;
int dist[M];
bool st[M];

void add(int a, int b, int c){
    
    
	e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;
}

void dijkstra(){
    
    
	priority_queue<PII, vector<PII>, greater<PII>> heap;
	memset(dist, 0x7f, sizeof dist);
	//cout << dist[t] << endl;
	//if (dist[t] == 0x7f7f7f7f)  cout << "------" << endl;
	dist[s] = 0;
//	st[s] = true;
	heap.push({
    
    0, s});
	
	while(heap.size()){
    
    
		auto t = heap.top();
		heap.pop();
		
		int ver = t.second, distance = t.first;
		
	//	cout << ver << " " << distance << "--------" << endl;
		if (st[ver])   continue;
		st[ver] = true;
		
		for (int i = h[ver]; ~i; i = ne[i]){
    
    
			int j = e[i];
			if (distance + w[i] < dist[j]){
    
    
				dist[j] = distance + w[i];
				heap.push({
    
    dist[j], j});
			}   
		}
	}
	
}

signed main(){
    
    
	scanf("%lld%lld%lld%lld", &n, &m, &s, &t);
	int edx = n + 1;
	
	memset(h, -1, sizeof h);
	for (int i = 1; i <= m; i ++){
    
    
		int w1, w2;
		scanf("%lld%lld", &w1, &w2);
		int cnt;
		gt(cnt);
		bool flag = false;
		while(cnt --){
    
    
			int x;
			scanf("%lld", &x);
			add(edx, x, w1), add(x, edx, 0);
		//	cout << edx << "----" << x << "----" << w1 << endl;
			if (flag){
    
    
				add(edx, edx - 1, w2);
				add(edx - 1, edx, w2);
			//	cout << edx - 1 << "---" << edx << "----" << w2 << endl;
			}
			else  flag = true;
			edx ++;
		}
	}
	
	 dijkstra();
	 if (dist[t] == 9187201950435737471)   cout << "-1" << endl;
	 else   cout << dist[t] << endl;
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45772483/article/details/112862754