题目链接
一.题目内容
给一个双向图,点是地铁站,边是轨道,每条边都有不同的轨道线编号,轨道往返所需时间一样。换线额外需要 两条线路的编号之差绝对值 的时间。求从 1 号地铁站到 n 号地铁站的最短时间。
样例解释
样例二:从1->n有两种路线 ①1->2->3 花费两条轨道时间1+1,以及从1号线换到2号线的时间1,总共时间3。②1->3 花费轨道时间10。最后结果是3
二.解题思路
很明显是一个单源最短路的题目,但是如果是点到点的话,每次到达某个点所乘的轨道线编号可能不同,如果创一个不同轨道线到达点的最短路径数组的话大小就10^10了会爆,所以干脆就采用边到边的最短路,dijkstra里面堆里存的边代表着通过某条边号到达的该点。然后从所有到达n的边取最小值。
三.解题代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i=l;i<=r;++i)
#define rrep(i,l,r) for(int i=l;i>=r;--i)
#define int long long
int dir[4][2]= {{-1,0},{0,-1},{1,0},{0,1}};
const int N=1e6+10,M=1e9+7;
//-----------//
struct node {
int v,w,c,id; //v为点,w为时间,c为轨道线号,id为边号
friend bool operator < (const node&t1,const node &t2) {
return t1.w>t2.w;
}
};
int n,m;
vector<node>a[N];
int dis[N];
int dj() {
rep(i,1,2*m) dis[i]=LLONG_MAX;
priority_queue<node>q;
for(auto i:a[1]){
q.push(node{i.v,i.w,i.c,i.id}); //优先队列里存边
}
while(q.size()) {
node cur=q.top();
q.pop();
if(cur.v==n) return cur.w; //按dijkstra算法性质,第一个从堆里出来的值即为边最短路,也为该边到达的点的最短路
for(auto i:a[cur.v]) {
int d=cur.w+i.w+abs(cur.c-i.c);
if(d<dis[i.id]) {
dis[i.id]=d;
q.push(node{i.v,d,i.c,i.id});
}
}
}
}
signed main() {
sync;
while(cin>>n>>m) {
rep(i,1,n) a[i].clear();
int x,y,c,d;
rep(i,1,m*2) {
cin>>x>>y>>c>>d;
a[x].push_back(node{y,d,c,i});
a[y].push_back(node{x,d,c,++i});
}
cout<<dj()<<endl;
}
}

本文介绍了2016年湖南省大学生程序设计大赛中关于地铁线路的题目,探讨了如何求解从1号地铁站到n号地铁站的最短时间。关键在于利用边到边的最短路径算法Dijkstra,解决点到点因换线导致的复杂度问题。代码实现和解题思路详尽阐述。

&spm=1001.2101.3001.5002&articleId=127234968&d=1&t=3&u=1bd92d8c4b9a4cc4b73feb5352282319)
1732

被折叠的 条评论
为什么被折叠?



