洛谷 P1251 餐巾计划问题(费用流)

题意:中文题

思路:直接按照题目上的描述建费用流即可,不过流量上限还是挺有意思的

代码:(爆了4 5发long long)

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

struct Min_cost_flow
{
    int S,T;
    long long ans=0;
    int vis[100010],vis2[100010];
    int d[100010],head[100010],to[100010],nextt[100010],w[100010],cost[100010];
    int tot = 2;
    int inf=0x7fffffff;
    void init(int _s,int _t)
    {
        S=_s;T=_t;
        memset(head,0,sizeof(head));
        ans=0;tot=2;
    }
    void add(int u,int v,int cap,int co)
    {
        cost[tot]=co;
        w[tot]=cap;
        to[tot]=v;
        nextt[tot]=head[u];
        head[u]=tot++;
        cost[tot] = -co;
        w[tot]=0;
        to[tot]=u;
        nextt[tot]=head[v];
        head[v]=tot++;
    }
    bool spfa()
    {
        memset(vis,0,sizeof(vis));
        memset(vis2,0,sizeof(vis2));
        for(int i = 1;i<=T;i++)d[i]=inf;
        queue<int> q;
        q.push(S);
        d[S]=0;
        vis[S]=1;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[u]=0;
            for(int i = head[u];i;i=nextt[i])
            {
                int v = to[i];
                if(w[i] && d[v]>d[u]+cost[i])
                {
                    d[v]=d[u]+cost[i];
                    if(!vis[v])
                    {
                        vis[v]=1;
                        q.push(v);
                    }
                }
            }
        }
        return d[T]<inf;
    }
    int dfs(int u,int f)
    {
        if(u==T)
        {
            ans+=d[u] * f;
            return f;
        }
        int res=0;
        vis2[u]=1;
        for(int i=head[u];i;i=nextt[i])
        {
            int v = to[i];
            if (w[i] && !vis2[v] && d[v]==d[u]+cost[i])
            {
                int temp=dfs(v,min(f-res,w[i]));
                w[i] -= temp;
                w[i^1] += temp;
                res += temp;
                if(res == f)return res;
            }
        }
        return res;
    }
    long long MCMF()
    {
        while(spfa())dfs(S,inf);
        return ans;
    }
}mcmf;

int a[2005];

int main()
{
    int N=read();
    for(int i=1;i<=N;i++){
        a[i]=read();
    }
    int p=read(),m=read(),f=read(),n=read(),s=read();
    int S=0,T=N+N+1;
    mcmf.init(S,T);
    for(int i=1;i<=N;++i){
        mcmf.add(S,i,a[i],0);
        mcmf.add(i+N,T,a[i],0);
        mcmf.add(S,i+N,1e9,p);
        if(i+1<=N) mcmf.add(i,i+1,1e9,0);
        if(i+m<=N) mcmf.add(i,i+N+m,1e9,f);
        if(i+n<=N) mcmf.add(i,i+N+n,1e9,s);
    }
    printf("%lld
",mcmf.MCMF());
    return 0;
}
原文地址:https://www.cnblogs.com/lalalatianlalu/p/9833635.html