小雨坐地铁
鏈接:
時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 524288K,其他語言1048576K
64bit IO Format:%lld
題目描述
小雨所在的城市一共有 m 條地鐵線,分別標號為 1 號線,2 號線,……,m 號線。整個城市一共有 n 個車站,編號為 1~n 。其中坐 i 號線需要花費 ai的價格,每坐一站就需要多花費 bi的價格。i 號線有 ci個車站,而且這 ci個車站都已知,如果某一站有多條地鐵線經過,則可以在這一站換乘到另一條地鐵線,并且能多次換乘。現在小雨想從第 ss 個車站坐地鐵到第 t
個車站,地鐵等待時間忽略不計,求最少花費的價格,若不能到達輸出 -1 。(地鐵是雙向的,所以 s 可能大于 t)
輸入描述:
第一行輸入四個正整數 n,m,s,t分別表示車站個數,地鐵線數,起點站和終點站。 第二行到第 m + 1行,每行前三個數為
ai,bi,ci,分別表示坐 i 號線的價格,i 號線每坐一站多花的價格,i 號線車站個數。接下來 ci個數,表示 i
號線的每一個車站的編號,單調遞增。
輸出描述:
共一行,一個數表示最小花費,若不能到達輸出 -1 。
示例1
輸入
輸出
7說明
坐 1 號線:花費 2;
1→3:花費 2;
換乘 2 號線:花費 2;
3→4:花費 1;
所以最小總花費為 7 。
題解:
我也是毫無頭緒,不知道該怎么下手做,看完別人的題解,來講講自己的理解
我們要用到分層圖
建立m+1層圖,前m層自然就是每一條的地鐵線,但地鐵線是有可能交叉的,也就是擁有共同車站,所以在第m+1層給每個車站建立一個虛點,用于和前m層對應的車站相連,注意是建雙向邊,因為地鐵可來回,從虛點到地鐵線上需要花費,花費坐這條線的價格,從地鐵線上到虛點花費為0
具體可以看看圖:
例題中求1—>4 ,
從虛點1出發,到第一條線1,花費為2,
從1再到3 花費為2
從第一條線3再到虛點3 花費為0
虛點3到第二條線3 花費為2
從第二條線3到4 花費為1
總花費為7
代碼:
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 1e8+2; int n,m,s,t,head[maxn],dis[maxn],ant,x;; priority_queue<pair<int,int> ,vector<pair<int,int> >,greater<pair<int,int> > >q; struct Node{ int to,next,w; }edge[maxn<<1];void add(int u,int v,int w) {edge[ant].next = head[u];edge[++ant].to = v;edge[ant].w = w;head[u] = ant; } void dijkstra(int s) {int u,d,v;dis[s] = 0;q.push(pair<int,int> (0,s));while(!q.empty()){u = q.top().second;d = q.top().first;q.pop();if(d > dis[u]) continue;for(int i=head[u];i;i=edge[i].next){v = edge[i].to;if(dis[v] > dis[u]+edge[i].w){dis[v] = dis[u]+edge[i].w;q.push(pair<int,int> (dis[v],v));}}} } int main() { int a,b,c;cin>>n>>m>>s>>t;for(int i=1;i<=n*(m+1);++i) dis[i] = maxn;for(int i=1;i<=m;++i){cin>>a>>b>>c;int pre = -1;while(c--){cin>>x;if(pre != -1){add(i*n+x,i*n+pre,b);add(i*n+pre,i*n+x,b);}add(x,i*n+x,a);//虛邊到火車站費用是做這個火車的費用 add(i*n+x,x,0);//火車站到虛邊費用為0 pre = x;//存上一個車站 }}dijkstra(s);if(dis[t] == maxn) cout<<"-1";else cout<<dis[t];return 0; }總結
- 上一篇: 2C+1A:安克 100W 三口 GaN
- 下一篇: 牛客网【每日一题】4月22日 K-th