題目描述
輸入格式
輸入文件第 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
費用流
用類似於可重複揹包刪邊
注意這坑題慢洗可能比快洗要快(坑哭我)
#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;
}