[BZOJ3245]最快路线

题目链接:

Please contact lydsy2012@163.com!

是个权限题,也许你可以取DBZ

一个分层图最短路简单题。

因为从一个点向另一个点转移时要考虑当前的速度,所以要把速度加进状态表示之中。

把每一个点拆成\(500\)个节点,设\(Dis_{[x][v]}\)表示在点\(x\),速度为\(v\)时的最短时间。

直接跑最短路即可。这里用堆优化\(Dijkstra\)

时间复杂度 \(O(500nlog_2(500n))\)

#include <queue>
#include <cstdio>
#include <cstring>

int n,m,Ed;
int Head[155],Next[25005],To[25005],Len[25005],Spe[25005],En;
int Prex[155][505],Prev[155][505];
bool Vis[155][505];
double Dis[155][505];
struct Point
{
    int x,v;//地点,时间
    double d;//距离
    inline bool operator<(const Point &Ot)const{return d>Ot.d;}
};

inline void Add(int x,int y,int l,int v)
{
    Next[++En]=Head[x];
    To[Head[x]=En]=y;
    Len[En]=l,Spe[En]=v;//长度,限速
}

void Dijkstra()
{
    std::priority_queue<Point> q;
    q.push((Point){1,70,0});
    memset(Dis,127,sizeof Dis);
    Dis[1][70]=0;
    while(!q.empty())
    {
        int x=q.top().x,v=q.top().v;
        double d=q.top().d;
        q.pop();
        if(Vis[x][v])continue;
        Vis[x][v]=true;
        for(int i=Head[x],y;i;i=Next[i])
        {
            int wv=Spe[i]?Spe[i]:v;//下一次的速度
            double t=(double)Len[i]/wv;//需要的时间
            if(Dis[y=To[i]][wv]>d+t)
            {
                Prex[y][wv]=x,Prev[y][wv]=v;//记录前驱,二元组
                q.push((Point){y,wv,Dis[y][wv]=d+t});
            }
        }
    }
}

void Print(int x,int v)
{//递归输出
    if(Prex[x][v])Print(Prex[x][v],Prev[x][v]);
    printf("%d%c",x-1,x==Ed?'\n':' ');
}

int main()
{
    scanf("%d%d%d",&n,&m,&Ed),++Ed;
    for(int a,b,v,l;m--;)
    {
        scanf("%d%d%d%d",&a,&b,&v,&l);
        Add(a+1,b+1,l,v);
    }
    Dijkstra();
    int Mp=0;
    for(int i=1;i<=500;++i)
        if(Dis[Ed][i]<Dis[Ed][Mp])
            Mp=i;//找到最快的点
    Print(Ed,Mp);
    return 0;
}

转载于:https://www.cnblogs.com/LanrTabe/p/10192265.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值