记录编号 |
240290 |
评测结果 |
AAAAAAAAAAAA |
题目名称 |
[网络流24题] 餐巾 |
最终得分 |
100 |
用户昵称 |
stdafx.h |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
2.953 s |
提交时间 |
2016-03-22 17:17:05 |
内存使用 |
52.88 MiB |
显示代码纯文本
- #define maxn 5010ul
- #define maxe 3000010ul
-
- #include <queue>
- #include <stdio.h>
- #include <string.h>
-
- struct pii{int x,y;};
- struct Edge{int u,v,nx,w,c;};
- Edge edge[maxe];
- int n,ec=1,headlist[maxn],S,T2,T,cnt,min_cost,A,B,f,fA,fB,tot,dis[maxn],flow[maxn],from[maxn],id[maxn][2],seq[maxn],must[maxn];
- bool ex[maxn];
- const int inf=0x3fffffff;
- std::queue<int> que;
-
- void Add_Edge(int u,int v,int w,int c){
- edge[++ec]=(Edge){u,v,headlist[u],w,c};
- headlist[u]=ec;
- return;
- }
-
- void Add(int u,int v,int w,int c){
- Add_Edge(u,v,w,c);
- Add_Edge(v,u,0,-c);
- return;
- }
-
- bool spfa(int &cost){
- memset(dis,0x2f,sizeof(dis));
- memset(flow,0,sizeof(flow));
- memset(from,0,sizeof(from));
- memset(ex,0,sizeof(ex));
- que.push(S);flow[S]=inf,dis[S]=0;
- while(!que.empty()){
- int p=que.front();que.pop();ex[p]=false;
- for(int i=headlist[p];i;i=edge[i].nx) if(edge[i].w>0&&dis[edge[i].v]>dis[p]+edge[i].c){
- dis[edge[i].v]=dis[p]+edge[i].c,from[edge[i].v]=i;
- flow[edge[i].v]=std::min(flow[p],edge[i].w);
- if(!ex[edge[i].v]) ex[edge[i].v]=true,que.push(edge[i].v);
- }
- }
- if(dis[T]>(int)(1e8)) return false;
- cost+=flow[T]*dis[T];
- for(int i=T;i;i=edge[from[i]].u) edge[from[i]].w-=flow[T],edge[from[i]^1].w+=flow[T];
- return true;
- }
-
- int mcmf(){
- int ans=0;
- while(spfa(ans));
- return ans;
- }
-
- bool check(int mid){
- ec=1;
- memset(headlist,0,sizeof(headlist));
- for(int i=1,x;i<=n;i++){
- x=seq[i];
- Add(S,id[i][0],inf,f);
- Add(id[i][0],id[i][1],x,-100000),must[i]=ec-1;
- if(i!=n) Add(id[i][0],id[i+1][0],inf,0);
- if(i+A<=n) Add(id[i][1],id[i+A][0],inf,fA);
- if(i+B<=n) Add(id[i][1],id[i+B][0],inf,fB);
- Add(id[i][1],T2,inf,0);
- }
- Add(T2,T,mid,0);min_cost=mcmf();
- for(int i=1;i<=n;i++) if(edge[must[i]].w!=0) return false;
- return true;
- }
-
- int main(){
- freopen("napkin.in","r",stdin);
- freopen("napkin.out","w",stdout);
- scanf("%d",&n);
- for(int i=1;i<=n;i++) scanf("%d",&seq[i]),tot+=seq[i];
- scanf("%d%d%d%d%d",&f,&A,&fA,&B,&fB);
- for(int i=1;i<=n;i++) id[i][0]=++cnt,id[i][1]=++cnt;T2=++cnt,T=++cnt;
- int L=0,R=tot,mid,a1,a2,mid2,ans_lower=-1,ans=0x2fffffff;
- while(L<=R){
- mid=(L+R)>>1;
- if(check(mid)) R=mid-1,ans_lower=mid;
- else L=mid+1;
- }
- L=ans_lower,R=tot;
- while(L<=R){
- mid=(L+R)>>1,mid2=(L+mid)>>1;
- check(mid),a1=min_cost;
- check(mid2),a2=min_cost;
- ans=std::min(ans,std::min(a1,a2));
- if(a1>a2) R=mid-1;
- else L=mid2+1;
- }
- if(ans!=-1) printf("%d",ans+tot*100000);
- else printf("%d",tot*f);
- return 0;
- }