Train-Dijkstra优先队列优化

Train-Dijkstra优先队列优化

链接
链接

题解
求指定两点最短路。可以看作Dijkstra板子题目,只是更新的时候考虑列车发车时间做上取整。

代码

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<iomanip>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<string.h>
#include<time.h>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cctype>
using namespace std;
#define ll  long long
#define ull unsigned long long
inline int read() {
    char ch = getchar(); int x = 0, f = 1;
    while(ch < '0' || ch > '9') {
        if(ch == '-') f = -1;
        ch = getchar();
    } while('0' <= ch && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    } return x * f;
}
ll mod=1e9+7;
ll INF=0x3f3f3f3f3f3f3f3f;
int Inf=0x3f3f3f3f;
 
struct node
{
    int id;
    ll val;
    node(int _i = 0, ll _v = 0) : id(_i), val(_v) { }
    bool operator<(const node& n) const
	{
		return val > n.val;
	}
};

const int nsize=1e5+5;
const int msize=1e5+5;

int hd[nsize],des[msize<<1],depa[msize<<1],cst[msize<<1],nxt[msize<<1];
int cnt=0;
bool vis[nsize];
ll dis[nsize];
priority_queue<node> pq;
int n,m,sx,tx;

void add_edge(int a,int b,int t,int k)
{
    des[cnt]=b;
    depa[cnt]=k;
    cst[cnt]=t;
    nxt[cnt]=hd[a];
    hd[a]=cnt++;
}
ll expd(ll a,ll b)  
{
    return (a/b*b)+((a%b)?b:0);
}
int main()
{
    ios::sync_with_stdio(0);
	cin.tie(0);
 
    memset(hd,-1,sizeof(hd));
    memset(dis,INF,sizeof(dis));
    memset(vis,0,sizeof(vis));

    n=read();
    m=read();
    sx=read()-1;
    tx=read()-1;
    int ta,tb,tt,tk;
    for(int i=0;i<m;++i)    
    {
        ta=read()-1;
        tb=read()-1;
        tt=read();
        tk=read();
        add_edge(ta,tb,tt,tk);
        add_edge(tb,ta,tt,tk);
    }

    node now;
    now.id=sx;
    now.val=0;
    pq.push(now);
    dis[sx]=0;
    while(!pq.empty())  
    {
        now=pq.top();
        pq.pop();
        if(!vis[now.id])
        {
            vis[now.id]=1;
            for(int p=hd[now.id];p!=-1;p=nxt[p])
            {
                if(dis[des[p]]>expd(dis[now.id],depa[p])+cst[p])
                {
                    dis[des[p]]=expd(dis[now.id],depa[p])+cst[p];
                    if(!vis[des[p]])
                    {
                        pq.push(node(des[p],dis[des[p]]));
                    }
                }
            }
        }
    }
    if (dis[tx] == INF)
		puts("-1");
	else
		printf("%lld\n", dis[tx]);


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值