• luogu P1251 餐巾计划问题 最小费用最大流


    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<iostream>
    using namespace std;
    const int maxn=200010;
    #define int long long
    bool vis[maxn];
    int n,m,s,t,x,y,z,f,cost[maxn],pre[maxn],last[maxn],flow[maxn],maxflow,mincost;
    //cost最小花费;pre每个点的前驱;last每个点的所连的前一条边;flow源点到此处的流量
    //maxflow 最大流量
    //mincost 最大流量的情况下的最小花费
    struct Edge
    {
        int to,next,flow,cost;//flow流量 cost花费
    } edge[maxn];
    int head[maxn],num_edge;
    queue <int> q;
    int t1,m1,t2,m2;
    #define INF 2147483647
    void add(int from,int to,int flow,int cost)
    {
        edge[++num_edge].next=head[from];
        edge[num_edge].to=to;
        edge[num_edge].flow=flow;
        edge[num_edge].cost=cost;
        head[from]=num_edge;
    
        edge[++num_edge].next=head[to];
        edge[num_edge].to=from;
        edge[num_edge].flow=0;
        edge[num_edge].cost=-cost;
        head[to]=num_edge;
    }
    bool spfa(int s,int t)
    {
        memset(cost,0x7f,sizeof(cost));
        memset(flow,0x7f,sizeof(flow));
        memset(vis,0,sizeof(vis));
        q.push(s);
        vis[s]=1;
        cost[s]=0;
        pre[t]=-1;
        while (!q.empty())
        {
            int now=q.front();
            q.pop();
            vis[now]=0;
            for (int i=head[now]; i!=-1; i=edge[i].next)
            {
                if (edge[i].flow>0 && cost[edge[i].to]>cost[now]+edge[i].cost)//正边
                {
                    cost[edge[i].to]=cost[now]+edge[i].cost;
                    pre[edge[i].to]=now;
                    last[edge[i].to]=i;
                    flow[edge[i].to]=min(flow[now],edge[i].flow);//
                    if (!vis[edge[i].to])
                    {
                        vis[edge[i].to]=1;
                        q.push(edge[i].to);
                    }
                }
            }
        }
        return pre[t]!=-1;
    }
    
    void MCMF()
    {
        while (spfa(s,t))
        {
            int now=t;
            maxflow+=flow[t];
            mincost+=flow[t]*cost[t];
            while (now!=s)
            {
                //从源点一直回溯到汇点
                edge[last[now]].flow-=flow[t];//flow和cost容易搞混
                edge[last[now]^1].flow+=flow[t];
                now=pre[now];
            }
        }
    }
    signed main()
    {
        memset(head,-1,sizeof(head));
        num_edge=-1;
        cin>>n;
        s=0,t=n*2+1;
        int x;
        for (int i=1; i<=n; i++)
        {
            cin>>x;//拆点 
            add(s,i,x,0);//每天晚上从起点获得x条脏餐巾 
            add(i+n,t,x,0);;//每天白天,向汇点提供x条干净的餐巾,流满时表示第i天的餐巾够用 
        }
        scanf("%d %d %d %d %d",&m,&t1,&m1,&t2,&m2);
        for(int i=1; i<=n; i++)
        {
            if(i+1<=n) 
                add(i,i+1,INF,0);//每天晚上可以将脏餐巾留到第二天晚上
            if(i+t1<=n) add(i,i+n+t1,INF,m1);//每天晚上可以送去快洗部,在地i+t1天早上收到餐巾
            if(i+t2<=n) add(i,i+n+t2,INF,m2);//每天晚上可以送去慢洗部,在地i+t2天早上收到餐巾
            add(s,i+n,INF,m);//每天早上可以购买餐巾
        }
        MCMF();
        cout<<mincost<<endl;
        return 0;
    }
  • 相关阅读:
    win10 点击开始按钮无反应
    Server Error in '/' Application. IIS拒绝访问
    vs2017添加引用时报错未能正确加载“ReferenceManagerPackage”包。
    关于JavaScript中的this指向问题
    4p-在一张图片中根据矩形四个点的坐标计算两个矩形是否相交
    opencv使用
    [VMware]虚拟网络编辑器
    [所思所想]观《长津湖》有感
    [项目管理]失败的软件项目所具备的特点【待续】
    [软件过程/软件生命周期模型]软件过程的工具链【待续】
  • 原文地址:https://www.cnblogs.com/QingyuYYYYY/p/13181723.html
Copyright © 2020-2023  润新知