题意:
• 一个餐厅在相继的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; }