C - 地铁 CSU - 维护边最短路

  • 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;
    }
    

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值