题意:
• 一个餐厅在相继的N 天里,每天需用的餐巾数不尽相同。假设第i天需要ri块餐巾(i=1,2,…,N)。餐厅可以购买新的餐巾,每块餐巾的费用为p分;或者把旧餐巾送到快洗部,洗一块需m天,其费用为f 分;或者送到慢洗部,洗一块需n 天(n>m),其费用为s<f 分。每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗。但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量。试设计一个算法为餐厅合理地安排好N 天中餐巾使用计划,使总的花费最小。
编程任务:编程找出一个最佳餐巾使用计划.
题解:
这个题解讲的真不错
• 给每天建两个点:代表这一天需要的干净毛巾和结束时候的脏毛巾
• 干净毛巾来源:新买的/之前送去洗洗好的——S向他连容量ri价格p的边/m天前的脏毛巾向他连容量inf价格f的边,n天前的脏毛巾向他连容量inf价格S的边
• 脏毛巾来源:今天用脏的/之前用脏没洗的——S向他连容量ri,价格0的边,表示这一天会产生ri个脏毛巾/前一天的脏毛巾向他连容量inf,价格0的边。
• 第i天需要有ri个干净毛巾——即至少要有ri的流量流向第i天的干净毛巾——即ri向T连一条ri的边
存在问题
建图我也会了,模板也打对,但是答案就是蜜汁错误,而且是一个点都没过,希望有大佬能帮我看一看啥问题
代码:
#include<bits/stdc++.h>
#define mem(x,a) memset(x,a,sizeof(x))
#define inf 1e9+7
typedef long long ll;
using namespace std;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
return s*w;
}
const int maxn=3e5+9;
struct node{
int u,v,w,next,dis;
}edge[maxn];
int cnt=1,head[maxn];
int a[maxn];
void add_edge(int u,int v,int w,int dis)
{
edge[++cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
edge[cnt].dis=dis;
head[u]=cnt;
}
void add(int u,int v,int w,int dis)
{
add_edge(u,v,w,dis);
add_edge(v,u,0,-dis);
}
int flow[maxn],dis[maxn],link[maxn],vis[maxn],pre[maxn];
int n,S=0,T=2*n+1,p,m,f,w,s;
bool spfa()
{
mem(vis,0);
mem(dis,0x3f3f3f);
mem(pre,-1);
queue<int>q;
vis[S]=1;
dis[S]=0;
pre[S]=0;
flow[S]=inf;
q.push(S);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].v;
int w=edge[i].w;
int d=edge[i].dis;
if(w>0&&dis[v]>dis[u]+d)
{
dis[v]=dis[u]+d;
pre[v]=u;
link[v]=i;
flow[v]=min(flow[u],w);
if(!vis[v])
{
q.push(v);
vis[v]=1;
}
}
}
}
return pre[T]!=-1;
}
inline int mcmf()
{
int sum=0;
while(spfa())
{
int k=T;
while(k!=S)
{
edge[link[k]].w-=flow[T];
edge[link[k]^1].w+=flow[T];
k=pre[k];
}
sum+=flow[T]*dis[T];
}
return sum;
}
int main()
{
cin>>n;
cin>>p>>m>>f>>w>>s;
/*
p 是每块新餐巾的费用;
mm 是快洗部洗一块餐巾需用天数;
ff 是快洗部洗一块餐巾需要的费用;
w 是慢洗部洗一块餐巾需用天数;
ss 是慢洗部洗一块餐巾需要的费用。
*/
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)
{
add(S,i,a[i],0);
}
for(int i=1;i<=n;i++)
{
if(i+m<=n)add(i,i+n+m,inf,f);
if(i+w<=n)add(i,i+n+w,inf,s);
if(i+1<=n)add(i,i+1,inf,0);
add(i+n,T,a[i],0);
add(S,i+n,inf,p);
}
cout<<mcmf()<<endl;
}

京公网安备 11010502036488号