Given a value E to find the most path from the beginning to the end of the line so that the sum of the length is not more than E
K Short-circuit A * algorithm ... Each point has a valuation function =g[x]+h[x] g[x] is the length from the source point has been gone h[x] is the shortest from this point to the meeting point
First run on the inverse of the SPFA to find out each point of the h[x], and then the source point of the g[x]+h[x] increase the heap each time the heap is removed from the top of the heap g[x] to the connected edge extension K times to remove the meeting point is the answer
One of the pruning is that when the first k+1 to take out a point does not continue to expand to prevent mle but here K unknown we can evaluate K processing initial k=floor (e/shortest short-circuit length) and then update K K=cnt[n]+floor each time the meeting point is removed (e/the current path length)
The more bereavement is this card priority_queue ... The memory of this thing is twice times the handwritten heap because the card memory so will hang can be handwritten heap I wrote can and Heap + garbage collection ...
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include < Algorithm> #define M 5050using namespace std;struct abcd{int pos; Double g,h; BOOL operator < (const ABCD &x) Const {return g + H < x.g + x.h; }};struct heap{ABCD Num; Heap *ls,*rs; void* operator new (size_t size,int pos,double g,double h); void operator Delete (void* p);} *root,*mempool,*c;struct edge{int to,next; Double F;} Table[400400];int head[m],tot=1;bool flag;queue<void*> bin;int n,m,k,ans,cnt[m];d ouble e,f[M];void* Heap:: operator new (size_t size,int pos,double g,double h) {if (!bin.empty ()) {Heap *re= (heap*) Bin.front (); Bin.pop (); re->num.pos=pos; re->num.g=g; re->num.h=h; re->ls=re->rs=0x0; return re; } if (C==mempool) {c=new heap[1<<15]; mempool=c+ (1<<15); } c->num.pos=pos; c->num.g=g; C->num.h=h; c->ls=c->rs=0x0; return C + +;} void Heap:: operator delete (void *p) {Bin.push (P);} heap* Merge (Heap *x,heap *y) {if (!x) return y; if (!y) return x; if (Y->num < x->num) swap (x, y); if (flag^=1) X->ls=merge (x->ls,y); else X->rs=merge (x->rs,y); return x;} inline void Insert (int pos,double g,double h) {Root=merge (Root,new (pos,g,h) Heap);} inline void Pop () {delete root; Root=merge (ROOT->LS,ROOT->RS);} void Add (int x,int y,double z) {table[++tot].to=y; Table[tot].f=z; TABLE[TOT].NEXT=HEAD[X]; Head[x]=tot;} void Spfa () {static int q[1<<16]; static unsigned short r,h; static bool V[m]; int i; Memset (f,0x42,sizeof f); F[n]=0;q[++r]=n; while (r!=h) {int x=q[++h];v[x]=0; for (I=head[x];i;i=table[i].next) if (i&1 && f[table[i].to]>f[x]+table[i].f) { F[TABLE[I].TO]=F[X]+TABLE[I].F; if (!v[table[i].to]) v[table[i].to]=1,q[++r]=table[i].to; }}}void A_star () {int i; K=static_cast<int> (e/f[1]) +1; Insert (1,0,f[1]); while (root) {ABCD x=root->num; Pop (); if (++cnt[x.pos]>k) continue; if (x.pos==n) {if (e-x.g<0) return; E-=x.g;++ans; K=cnt[n]+static_cast<int> (E/X.G) +1; } for (I=head[x.pos];i;i=table[i].next) if (~i&1) Insert (table[i].to,x.g+table[i].f,f[t Able[i].to]); }}int Main () {int i,x,y; Double Z; cin>>n>>m>>e; for (i=1;i<=m;i++) {scanf ("%d%d%lf", &x,&y,&z); ADD (x, y, z); ADD (Y,X,Z); } SPFA (); A_star (); cout<<ans<<endl; return 0;}
Bzoj 1975 SDOI2010 Magic Pig Academy a*k Short Circuit