【CodeForces】【311C】Fetch the Treasures

最短路


  神题一道……

 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 }
View Code

转载于:https://www.cnblogs.com/Tunix/p/4360987.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值