SP338ROADS題解--最短路變式
阿新 • • 發佈:2018-09-14
分析 ffffff set pop etc amp getchar else gis
題目鏈接
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; }
SP338ROADS題解--最短路變式