题意:

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