2016年湖南省第十二届大学生程序设计大赛 题 “地铁” CSG - 1139(边到边最短路,dijkstra)

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

题目链接


一.题目内容

给一个双向图,点是地铁站,边是轨道,每条边都有不同的轨道线编号,轨道往返所需时间一样。换线额外需要 两条线路的编号之差绝对值 的时间。求从 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;
    }
}





四.小结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值