zoukankan      html  css  js  c++  java
  • P2517 [HAOI2010]订货

    思路

    费用流水题
    对每月拆点,入点向出点连cap=ui的边,s向入点连cost=di的边,i的入点向i+1的入点连cap=S的边即可

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <vector>
    using namespace std;
    struct Edge{
        int u,v,cap,flow,cost;	
    };
    const int MAXN = 5001;
    const int INF = 0x3f3f3f3f;
    vector <Edge> edges;
    vector <int> G[MAXN];
    int n,m,s,t,S;
    int a[MAXN],p[MAXN],d[MAXN];
    bool vis[MAXN];
    void addedge(int u,int v,int cap,int cost){
        edges.push_back((Edge){u,v,cap,0,cost});
        edges.push_back((Edge){v,u,0,0,-cost});
        int cnt=edges.size();
        G[u].push_back(cnt-2);
        G[v].push_back(cnt-1);
    }
    bool spfa(int s,int t,int &cost,int &flow){
        memset(d,0x3f,sizeof(d));
        memset(vis,0,sizeof(vis));
        d[s]=0;p[s]=0;a[s]=0x3f3f3f3f;
        queue<int> q;
        q.push(s);
        vis[s]=true;
        while(!q.empty()){
            int x=q.front();q.pop();
            vis[x]=false;
            for(int i=0;i<G[x].size();i++){
                Edge &e=edges[G[x][i]];
                if(e.cap>e.flow&&d[e.v]>d[x]+e.cost){
                    d[e.v]=d[x]+e.cost;
                    p[e.v]=G[x][i];
                    a[e.v]=min(a[x],e.cap-e.flow);
                    if(!vis[e.v]){
                        q.push(e.v);
                        vis[e.v]=true;
                    }
                }
            }
        }
        if(d[t]==0x3f3f3f3f)
            return false;
        flow+=a[t];
        cost+=d[t]*a[t];
        for(int u=t;u!=s;u=edges[p[u]].u){
            edges[p[u]].flow+=a[t];
            edges[p[u]^1].flow-=a[t];
        }
        return true;
    }
    void MFMC(int s,int t,int &flow,int &cost){
        flow=0;
        cost = 0;
        while(spfa(s,t,cost,flow));
        return;
    }
    int main(){
        s=MAXN-2;
        t=MAXN-3;
        scanf("%d %d %d",&n,&m,&S);
        for(int i=1;i<=n;i++){
            int mid;
            scanf("%d",&mid);
            addedge(i,i+n,mid,0);
            addedge(i+n,t,INF,0);
        }
        for(int i=1;i<=n;i++){
            int mid;
            scanf("%d",&mid);
            addedge(s,i,INF,mid);
            if(i!=n)
                addedge(i,i+1,S,m);
        }
        int flow,cost;
        MFMC(s,t,flow,cost);
        printf("%d
    ",cost);
        return 0;
    }
    
  • 相关阅读:
    记一道乘法&加法线段树(模版题)
    2021CCPC网络赛(重赛)题解
    Codeforces Round #747 (Div. 2)题解
    F. Mattress Run 题解
    Codeforces Round #744 (Div. 3) G题题解
    AtCoder Beginner Contest 220部分题(G,H)题解
    Educational Codeforces Round 114 (Rated for Div. 2)题解
    Codeforces Global Round 16题解
    Educational Codeforces Round 113 (Rated for Div. 2)题解
    AtCoder Beginner Contest 182 F
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10538301.html
Copyright © 2011-2022 走看看