您的位置:首页 > 编程语言

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 





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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  代码 算法