-
B - 星系碰撞
- FZU - 2194
- 题意:
- 换乘线路很麻烦。如果乘坐第 i 段地铁来到地铁站 s,又乘坐第 j 段地铁离开地铁站 s,那么需要额外花费 |c i-c j | 分钟。注意,换乘只能在地铁站内进行。
- Bobo 想知道从地铁站 1 到地铁站 n 所需要花费的最小时间
- 思路:
- 给边编号,dis记录以此边结束的路线的总时间进行最短路更新。
- 注意在建图过程中记录边的编号保证能通过编号访问到边并且能从边找到点亦能从点找到边。
- 最后一点注意的就是在dijkstra里面进行不断更新能到达终点的边的时间就是到达终点的总时间不断维护最小值
-
#include<bits/stdc++.h> using namespace std; #define maxn 255555 #define inf 0x3f3f3f3f struct node { int v,w,cnt,id; } edge[maxn]; struct head { int order,num; friend bool operator<(head n1,head n2) { return n1.num>n2.num; } } dis[maxn]; int n,m,a,b,c,t,ans,maxx; vector<node>mmp[maxn]; void dij() { for(int i=1; i<=2*m; i++) { dis[i].num=inf; dis[i].order=i; } priority_queue<head>q; for(int i=0; i<mmp[1].size(); i++) { dis[mmp[1][i].cnt].num=mmp[1][i].w; q.push(dis[mmp[1][i].cnt]); // cout<<dis[mmp[1][i].cnt].num<<endl; } while(!q.empty()) { int u=q.top().order; q.pop(); if(edge[u].v==n) maxx=min(maxx,dis[u].num); // cout<<u<<" "<<edge[u].v<<" "<<maxx<<endl; for(int i=0; i<mmp[edge[u].v].size(); i++) { if(dis[mmp[edge[u].v][i].cnt].num>dis[u].num+mmp[edge[u].v][i].w+(abs(edge[u].id-mmp[edge[u].v][i].id))) { dis[mmp[edge[u].v][i].cnt].num=dis[u].num+mmp[edge[u].v][i].w+(abs(edge[u].id-mmp[edge[u].v][i].id)); q.push(dis[mmp[edge[u].v][i].cnt]); } } } } int main() { while(cin>>n>>m) { for(int i=1; i<=n; i++) mmp[i].clear(); maxx=inf; for(int i=1; i<=2*m; i++) { cin>>a>>b>>c>>t; edge[i].v=b; edge[i].w=t; edge[i].id=c; edge[i].cnt=i; mmp[a].push_back(edge[i]); edge[++i].v=a; edge[i].w=t; edge[i].id=c; edge[i].cnt=i; mmp[b].push_back(edge[i]); } dij(); // for(int i=1;i<=2*m;i++) // cout<<dis[i].num<<endl; cout<<maxx<<endl; } return 0; }