CSU1808地铁
Posted Dirge
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSU1808地铁相关的知识,希望对你有一定的参考价值。
ICPCCamp 有 n 个地铁站,用 1,2,…,n 编号。 m 段双向的地铁线路连接 n 个地铁站,其中第 i 段地铁属于 ci 号线,位于站 ai,bi 之间,往返均需要花费 ti 分钟(即从 ai 到 bi 需要 ti 分钟,从 bi 到 ai 也需要 ti 分钟)。
众所周知,换乘线路很麻烦。如果乘坐第 i 段地铁来到地铁站 s,又乘坐第 j 段地铁离开地铁站 s,那么需要额外花费 |ci-cj | 分钟。注意,换乘只能在地铁站内进行。
Bobo 想知道从地铁站 1 到地铁站 n 所需要花费的最小时间。
Input
输入包含不超过 20 组数据。
每组数据的第一行包含两个整数 n,m (2≤n≤105,1≤m≤105).
接下来 m 行的第 i 行包含四个整数 ai,bi,ci,ti (1≤ai,bi,ci≤n,1≤ti≤109).
保证存在从地铁站 1 到 n 的地铁线路(不一定直达)。
Output
对于每组数据,输出一个整数表示要求的值。
题解:分层图最短路。
每个地铁站按地铁线拆成若干站,这若干站之间按线号从小到大连,表示换乘地铁线。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define gg puts("gg"); 4 #define ll long long 5 #define mp make_pair 6 #define pii pair<int, int> 7 #define pli pair<ll, int> 8 #define fi first 9 #define se second 10 const int N = 1e5+50; 11 const ll inf = 1e16; 12 int n, m, tot; 13 struct edge{ 14 int to, w; 15 edge(int to, int w):to(to), w(w){} 16 edge(){} 17 }; 18 struct Edge{ 19 int f, to, w; 20 Edge(int f, int to, int w): f(f), to(to), w(w){} 21 Edge(){} 22 }; 23 vector<Edge> s[N]; 24 vector< pii > newv[N]; 25 vector<edge> ve[N*4];//// 26 ll d[N*2]; 27 void dijsktra(int n, int s){ 28 for(int i = 1; i <= n; i++) d[i] = inf; 29 priority_queue< pli, vector<pli>, greater< pli > > Q; 30 for(int i = 0; i < newv[s].size(); i++){ 31 int u = newv[s][i].se; 32 d[u] = 0; 33 Q.push( mp(0, u) ); 34 } 35 while(!Q.empty()){ 36 pli f = Q.top(); 37 Q.pop(); 38 ll dis = f.fi; 39 int x = f.se; 40 if(d[x] < dis) 41 continue ; 42 for(int i = 0; i < ve[x].size(); i++){ 43 int to = ve[x][i].to, w = ve[x][i].w; 44 if(d[to] > dis+w){ 45 d[to] = dis+w; 46 Q.push( mp(d[to], to) ); 47 } 48 } 49 } 50 } 51 52 int main(){ 53 int u, v; 54 while(~scanf("%d%d", &n, &m)){ 55 int a, b, c, t; 56 for(int i = 0; i < m; i++){ 57 scanf("%d%d%d%d", &a, &b, &c, &t); 58 s[c].push_back( Edge(a, b, t) ); 59 } 60 61 tot = 0; 62 for(int i = 1; i <= n; i++){ 63 for(int j = 0; j < s[i].size(); j++){ 64 int u = s[i][j].f, v = s[i][j].to, w = s[i][j].w; 65 if(newv[u].empty()||newv[u].back().first < i) newv[u].push_back( mp(i, ++tot) ); 66 if(newv[v].empty()||newv[v].back().first < i) newv[v].push_back( mp(i, ++tot) ); 67 int uu = newv[u].back().se, vv = newv[v].back().se; 68 ve[uu].push_back( edge(vv, w) ); 69 ve[vv].push_back( edge(uu, w) ); 70 } 71 } 72 for(int i = 1; i <= n; i++){ 73 for(int j = 1; j < newv[i].size(); j++){ 74 int u = newv[i][j-1].se, v = newv[i][j].se, w = newv[i][j].fi-newv[i][j-1].fi; 75 ve[u].push_back( edge(v, w) ); 76 ve[v].push_back( edge(u, w) ); 77 } 78 } 79 80 dijsktra(tot, 1); 81 ll ans = inf; 82 for(int i = 0; i < newv[n].size(); i++){ 83 int x = newv[n][i].se; 84 ans = min(ans, d[x]); 85 } 86 printf("%lld\n", ans); 87 88 for(int i = 1; i <= n; i++){ 89 s[i].clear(); 90 newv[i].clear(); 91 } 92 for(int i = 1; i <= tot; i++) 93 ve[i].clear(); 94 } 95 return 0; 96 }
以上是关于CSU1808地铁的主要内容,如果未能解决你的问题,请参考以下文章
[CSUOJ1808] 地铁(dijkstra,堆,边最短路)