记录编号 240290 评测结果 AAAAAAAAAAAA
题目名称 [网络流24题] 餐巾 最终得分 100
用户昵称 Gravatarstdafx.h 是否通过 通过
代码语言 C++ 运行时间 2.953 s
提交时间 2016-03-22 17:17:05 内存使用 52.88 MiB
显示代码纯文本
  1. #define maxn 5010ul
  2. #define maxe 3000010ul
  3.  
  4. #include <queue>
  5. #include <stdio.h>
  6. #include <string.h>
  7.  
  8. struct pii{int x,y;};
  9. struct Edge{int u,v,nx,w,c;};
  10. Edge edge[maxe];
  11. 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];
  12. bool ex[maxn];
  13. const int inf=0x3fffffff;
  14. std::queue<int> que;
  15.  
  16. void Add_Edge(int u,int v,int w,int c){
  17. edge[++ec]=(Edge){u,v,headlist[u],w,c};
  18. headlist[u]=ec;
  19. return;
  20. }
  21.  
  22. void Add(int u,int v,int w,int c){
  23. Add_Edge(u,v,w,c);
  24. Add_Edge(v,u,0,-c);
  25. return;
  26. }
  27.  
  28. bool spfa(int &cost){
  29. memset(dis,0x2f,sizeof(dis));
  30. memset(flow,0,sizeof(flow));
  31. memset(from,0,sizeof(from));
  32. memset(ex,0,sizeof(ex));
  33. que.push(S);flow[S]=inf,dis[S]=0;
  34. while(!que.empty()){
  35. int p=que.front();que.pop();ex[p]=false;
  36. for(int i=headlist[p];i;i=edge[i].nx) if(edge[i].w>0&&dis[edge[i].v]>dis[p]+edge[i].c){
  37. dis[edge[i].v]=dis[p]+edge[i].c,from[edge[i].v]=i;
  38. flow[edge[i].v]=std::min(flow[p],edge[i].w);
  39. if(!ex[edge[i].v]) ex[edge[i].v]=true,que.push(edge[i].v);
  40. }
  41. }
  42. if(dis[T]>(int)(1e8)) return false;
  43. cost+=flow[T]*dis[T];
  44. for(int i=T;i;i=edge[from[i]].u) edge[from[i]].w-=flow[T],edge[from[i]^1].w+=flow[T];
  45. return true;
  46. }
  47.  
  48. int mcmf(){
  49. int ans=0;
  50. while(spfa(ans));
  51. return ans;
  52. }
  53.  
  54. bool check(int mid){
  55. ec=1;
  56. memset(headlist,0,sizeof(headlist));
  57. for(int i=1,x;i<=n;i++){
  58. x=seq[i];
  59. Add(S,id[i][0],inf,f);
  60. Add(id[i][0],id[i][1],x,-100000),must[i]=ec-1;
  61. if(i!=n) Add(id[i][0],id[i+1][0],inf,0);
  62. if(i+A<=n) Add(id[i][1],id[i+A][0],inf,fA);
  63. if(i+B<=n) Add(id[i][1],id[i+B][0],inf,fB);
  64. Add(id[i][1],T2,inf,0);
  65. }
  66. Add(T2,T,mid,0);min_cost=mcmf();
  67. for(int i=1;i<=n;i++) if(edge[must[i]].w!=0) return false;
  68. return true;
  69. }
  70.  
  71. int main(){
  72. freopen("napkin.in","r",stdin);
  73. freopen("napkin.out","w",stdout);
  74. scanf("%d",&n);
  75. for(int i=1;i<=n;i++) scanf("%d",&seq[i]),tot+=seq[i];
  76. scanf("%d%d%d%d%d",&f,&A,&fA,&B,&fB);
  77. for(int i=1;i<=n;i++) id[i][0]=++cnt,id[i][1]=++cnt;T2=++cnt,T=++cnt;
  78. int L=0,R=tot,mid,a1,a2,mid2,ans_lower=-1,ans=0x2fffffff;
  79. while(L<=R){
  80. mid=(L+R)>>1;
  81. if(check(mid)) R=mid-1,ans_lower=mid;
  82. else L=mid+1;
  83. }
  84. L=ans_lower,R=tot;
  85. while(L<=R){
  86. mid=(L+R)>>1,mid2=(L+mid)>>1;
  87. check(mid),a1=min_cost;
  88. check(mid2),a2=min_cost;
  89. ans=std::min(ans,std::min(a1,a2));
  90. if(a1>a2) R=mid-1;
  91. else L=mid2+1;
  92. }
  93. if(ans!=-1) printf("%d",ans+tot*100000);
  94. else printf("%d",tot*f);
  95. return 0;
  96. }