AC日记——餐巾计划问题 洛谷 P1084
思路:
氧气优化水过;
代码:
#include <bits/stdc++.h> using namespace std; #define maxn 4005 #define maxque 1000005 #define INF 0x7fffffff #define ll long long ll n,head[maxn],E[maxque],V[maxque],W[maxque],F[maxque]; ll pi,qt,qc,st,sc,s,t,cnt=1,day[maxn],pre[maxn],dis[maxn]; ll que[maxque],ans; bool if_[maxn]; inline void in(ll &now) { char Cget=getchar();now=0; while(Cget>'9'||Cget<'0') Cget=getchar(); while(Cget>='0'&&Cget<='9') { now=now*10+Cget-'0'; Cget=getchar(); } } inline void edge_add(ll u,ll v,ll w,ll f) { E[++cnt]=head[u],V[cnt]=v,W[cnt]=w,F[cnt]=f,head[u]=cnt; E[++cnt]=head[v],V[cnt]=u,W[cnt]=-w,F[cnt]=0,head[v]=cnt; } bool spfa() { for(ll i=s;i<=t;i++)dis[i]=INF,if_[i]=false,pre[i]=-1; ll h=maxque>>1,tail=h+1,now;que[h]=s,if_[s]=true,dis[s]=0; while(h<tail) { now=que[h++],if_[now]=false; for(ll i=head[now];i;i=E[i]) { if(F[i]>0&&W[i]+dis[now]<dis[V[i]]) { pre[V[i]]=i,dis[V[i]]=dis[now]+W[i]; if(!if_[V[i]]) { if(dis[V[i]]<=dis[que[h]]&&h<tail) que[--h]=V[i]; else que[tail++]=V[i]; if_[V[i]]=true; } } } } return dis[t]!=INF; } int main() { in(n),s=0,t=n*2+1;ll pos,now; for(ll i=1;i<=n;i++)in(day[i]); in(pi),in(qt),in(qc),in(st),in(sc); for(ll i=1;i<=n;i++) { edge_add(s,i,pi,INF); edge_add(i,t,0,day[i]); edge_add(s,i+n,0,day[i]); if(i+qt<=n) edge_add(i+n,i+qt,qc,INF); if(i+st<=n) edge_add(i+n,i+st,sc,INF); if(i!=n) edge_add(i+n,i+n+1,0,INF); } while(spfa()) { now=t,pos=INF; while(pre[now]!=-1) { pos=min(pos,F[pre[now]]); now=V[pre[now]^1]; } now=t,ans+=dis[t]*pos; while(pre[now]!=-1) { F[pre[now]]-=pos; F[pre[now]^1]+=pos; now=V[pre[now]^1]; } } printf("%lld\n",ans); return 0; }