superoj441 餐巾计划
2015-10-08 19:48
369 查看
题目描述
输入格式
输入文件第 1 行有 6 个正整数 N,p,m,f,n,s。其中 N 是要安排餐巾使用计划的天数;p 是每块新餐巾的费用;m 是快洗部洗一块餐巾需用天数;f 是快洗部洗一块餐巾需要的费用;n 是慢洗部洗一块餐巾需用天数;s 是慢洗部洗一块餐巾需要的费用。数据范围如下:1≤N≤800,1≤p≤50,1≤m≤20, 1≤f≤20,1≤n≤20,1≤s≤10。接下来的 N 行是餐厅在相继的 N 天里,每天需用的餐巾数(每个数不超过500)。
输出格式
输出餐厅在相继的 N 天里使用餐巾的最小总花费。
样例数据 1
输入 [复制]3 10 2 3 3 2
5
6
7
输出
145
费用流
用类似于可重复背包删边
注意这坑题慢洗可能比快洗要快(坑哭我)
#include<cmath> #include<ctime> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<vector> using namespace std; struct node { int to; int next; int liu; int cost; int from; }; node bian[1300000]; int first[40010]; int dis[40010]; int xuqiu[40010]; int n,p,m,f,z,s; //p新餐巾费用 m快洗time f快洗费用 z慢洗time s慢洗费用 int size; queue <int> q; bool exsit[40000]; int zcost,zflow; int pre[40000]; void inser(int a,int b,int liu,int cost) { size++; bian[size].to=b; bian[size].next=first[a]; first[a]=size; bian[size].liu=liu; bian[size].from=a; bian[size].cost=cost; } void init() { int i,j; scanf("%d%d%d%d%d%d",&n,&p,&m,&f,&z,&s); for(i=1;i<=n;i++) { scanf("%d",&xuqiu[i]); } for(i=1;i<=n;i++) { inser(0,i,xuqiu[i],0); inser(i,0,0,0); } for(i=1;i<=n;i++) { inser(n+i,2*n+1,xuqiu[i],0); inser(2*n+1,n+i,0,0); } for(i=1;i<n;i++) { inser(i,i+1,10000000,0); inser(i+1,i,0,0); } for(i=1;i<=n;i++) { if(i+m<=n) { inser(i,i+n+m,10000000,f); inser(i+n+m,i,0,-f); } if(i+z<=n) { inser(i,i+n+z,10000000,s); inser(i+n+z,i,0,-s); } inser(0,n+i,10000000,p); inser(n+i,0,0,-p); } inser(4*n,0,100000000,0); } bool spfa() { while(!q.empty()) q.pop(); memset(dis,127,sizeof(dis)); memset(exsit,false,sizeof(exsit)); memset(pre,-1,sizeof(pre)); pre[0]=size; dis[0]=0; exsit[0]=true; q.push(0); while(!q.empty()) { int u=q.front(); q.pop(); exsit[u]=false; for(int i=first[u];i!=0;i=bian[i].next) { int d=bian[i].to; if(bian[i].liu!=0&&dis[d]>dis[u]+bian[i].cost) { dis[d]=dis[u]+bian[i].cost; pre[d]=i; if(!exsit[d]) { exsit[d]=true; // if(exsit[n*2+1]) return true; q.push(d); } } } } if(dis[2*n+1]>1000000000) return false; return true; } int flow_() { int flow; while(spfa()) { flow=0x7fffffff; for(int i=pre[2*n+1];bian[i].from!=4*n;i=pre[bian[i].from]) { if(bian[i].liu<flow) flow=bian[i].liu; } for(int i=pre[2*n+1];bian[i].from!=4*n;i=pre[bian[i].from]) { bian[i].liu-=flow; bian[i+1].liu+=flow; zcost+=flow*bian[i].cost; } zflow+=flow; } return zcost; } int main() { // freopen("lx.in","r",stdin); // freopen("lx.out","w",stdout); int i,j,k; init(); int ans=flow_(); cout<<ans; //cout<<zflow<<" "; // cout<<size; return 0; }
相关文章推荐
- android 代码实现控件之间的间距
- [Android]在代码里运行另一个程序的方法
- 肯特·贝克:改变人生的代码整理魔法
- 网页恶意代码的预防
- 动易2006序列号破解算法公布
- 高手写的Tracer-Flash代码调试类代码下载
- CSS代码缩写技巧
- 非主流Q-zOne代码代码搜集第1/2页
- Ruby实现的矩阵连乘算法
- CreateWeb.vbs 代码
- C#插入法排序算法实例分析
- Lua中编译执行代码相关的函数详解
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- 更有效率的css代码编写第1/3页
- 代码中到底应不应当写注释?