【CodeForces】【311C】Fetch the Treasures
最短路
神题一道……
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //CF 311C 2 #include<queue> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<iostream> 7 #include<algorithm> 8 #define rep(i,n) for(int i=0;i<n;++i) 9 #define F(i,j,n) for(int i=j;i<=n;++i) 10 #define D(i,j,n) for(int i=j;i>=n;--i) 11 #define pii pair<int,int> 12 #define mk make_pair 13 using namespace std; 14 typedef long long LL; 15 LL getint(){ 16 LL v=0,sign=1; char ch=getchar(); 17 while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();} 18 while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();} 19 return v*sign; 20 } 21 const int N=100010,INF=~0u>>2; 22 /*******************tamplate********************/ 23 priority_queue<pii >H; 24 LL a[N],d[N],data[25],z; 25 int n,m,k,x,y,L,ed[25],f[N*20],c[N]; 26 bool b[N]; 27 28 void add(){ 29 z=getint(); 30 data[++L]=z/k; ed[L]=z%k; 31 int h=0,t=0; rep(i,k) f[++t]=i; 32 while(h<t){ 33 x=f[++h],b[x]=0; 34 F(i,1,L){ 35 y=x+ed[i],z=d[x]+data[i]; if(y>=k) y-=k,z++; 36 if (z<d[y]) {d[y]=z;if(!b[y]) b[y]=1,f[++t]=y;} 37 } 38 } 39 while(!H.empty()) H.pop(); 40 F(i,1,n) 41 if(d[a[i]%k]<=a[i]/k && c[i]) H.push(mk(c[i],-i)); 42 } 43 void dec(){ 44 x=getint(); y=getint();c[x]-=y; 45 if (d[a[x]%k]<=a[x]/k) H.push(mk(c[x],-x)); 46 } 47 void pop(){ 48 while(1){ 49 if(H.empty()){puts("0");return;} 50 pii o=H.top(); H.pop(); x=-o.second,y=o.first; 51 if (c[x]==y) {printf("%d\n",y),c[x]=0; return;} 52 } 53 } 54 int main(){ 55 #ifndef ONLINE_JUDGE 56 freopen("input.txt","r",stdin); 57 // freopen("output.txt","w",stdout); 58 #endif 59 getint(); n=getint(); 60 m=getint(); k=getint(); 61 memset(d,1,sizeof d); d[1]=0; 62 F(i,1,n){ 63 a[i]=getint(); c[i]=getint(); 64 if (a[i]%k==1) H.push(mk(c[i],-i)); 65 } 66 int ch; 67 F(i,1,m){ 68 ch=getint(); 69 if (ch==1) add(); 70 else if(ch==2) dec(); 71 else pop(); 72 } 73 return 0; 74 }