SP338ROADS题解--最短路变式

题目链接

https://www.luogu.org/problemnew/show/SP338

分析

联想到不久前做过的一道题\(Full\) \(Tank\),感觉可以用优先队列做,于是写了\(dijsktra\)(非负权图不敢用\(SPFA\)了)

然后发现错了,想了挺久,发现它实际上是可以找\(dis\)更大的走以花费更少的钱,于是把\(vis\)数组和\(dis\)数组全去掉就A了

优先队列保证取出的距离是最短的,如果距离相同,那么钱数是最小的,所以第一次取出\(n\)时就是答案,跑得出乎意料的快

代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <queue>
#define ll long long 
#define ri register int 
using std::min;
using std::max;
using std::priority_queue;
template <class T>inline void read(T &x){
    x=0;int ne=0;char c;
    while(!isdigit(c=getchar()))ne=c=='-';
    x=c-48;
    while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
    x=ne?-x:x;return ;
}
const int maxn=10005;
const int inf=0x7fffffff;
struct Edge{
    int ne,to,dis,co;
}edge[maxn];
int h[maxn],num_edge=0;
inline void add_edge(int f,int to,int d,int co){
    edge[++num_edge].ne=h[f];
    edge[num_edge].to=to;
    edge[num_edge].dis=d;
    edge[num_edge].co=co;
    h[f]=num_edge;
}
struct Sta{
    int ver,dis,c;
    Sta(int x,int y,int z){ver=x,dis=y,c=z;}
    bool operator <(const Sta &b)const{
        return dis==b.dis?c<b.c:dis>b.dis;
    }
};
int n,m,k;
inline void dij(){
    Sta tmp=Sta{0,0,0};
    int u,v,d,val,ans=inf;
    priority_queue<Sta>q;
    while(q.size())q.pop();
    q.push(Sta(1,0,k));
    while(q.size()){
        tmp=q.top();q.pop();
        u=tmp.ver,d=tmp.dis,val=tmp.c;
        if(u==n){
            ans=d;
            break;
        }
        for(ri i=h[u];i;i=edge[i].ne){
            v=edge[i].to;
            if(val-edge[i].co>=0){
                q.push(Sta(v,d+edge[i].dis,val-edge[i].co));
            }
        }
    }
    if(ans==inf)puts("-1");
    else printf("%d\n",ans);
    return ;
}
int main(){
    int T,x,y,z,p;
    read(T);
    while(T--){
        read(k),read(n),read(m);
        num_edge=0;
        memset(h,0,sizeof(h));
        for(ri i=1;i<=m;i++){
            read(x),read(y),read(z),read(p);
            add_edge(x,y,z,p);
            //add_edge(y,x,z,p);
        }
        dij();
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Rye-Catcher/p/9648305.html