• POJ2516 Minimum Cost


    亲爱的,一个货物销售者,现在遇到了一个大问题,他需要你的帮助。在他的销售区域有 N 个店主(从 1 到 N)向他储存货物,Dearboy 有M 个供应点(从 1 到 M),每个供应点提供 K 种不同的货物(从 1 到K)。一旦店主订购货物,迪尔博伊应该安排哪个供应点向店主提供多少货物,以降低总的运输成本。众所周知,从不同的货源地向不同的店主运送不同种类的一件商品的成本可能是不同的。考虑到每个货源地存放的 K 种货物,N 个店主订购的K 种货物,以及从不同货源地向不同店主运送不同种类货物的成本,您应该说明如何安排货物的供应,以使运输总成本最小化。
     
    最小费用最大流模板~
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int maxn=1014;
    const int inf=1e9;
    int cap[maxn][maxn];
    int flow[maxn][maxn];
    int cost[maxn][maxn];
    int n;
    int f;//最大流 
    int c;//最小费用 
    int st,ed;
    bool visit[maxn];
    int pre[maxn],dist[maxn];
    bool spfa () {
        queue<int> q;
        for (int u=0;u<=n;u++) {
            if (u==st) {
                q.push(u);
                dist[u]=0;
                visit[u]=true;
            }
            else {
                dist[u]=inf;
                visit[u]=false;
            }
        }
        while (!q.empty()) {
            int u=q.front();
            visit[u]=false;
            q.pop();
            for (int v=0;v<=n;v++) {
                if (cap[u][v]>flow[u][v]&&dist[v]>dist[u]+cost[u][v]) {
                    dist[v]=dist[u]+cost[u][v];
                    pre[v]=u;
                    if (!visit[v]) {
                        visit[v]=true;
                        q.push(v);
                    }
                }
            }
        }
        if (dist[ed]>=inf) return false;
        return true;
    }
    void minCostMaxflow () {
        memset (flow,0,sizeof(flow));
        c=f=0;
        while (spfa()) {
            int Min=inf;
            for (int u=ed;u!=st;u=pre[u]) 
            Min=min(Min,cap[pre[u]][u]-flow[pre[u]][u]);
            for (int u=ed;u!=st;u=pre[u]) {
                flow[pre[u]][u]+=Min;
                flow[u][pre[u]]-=Min;
            }
            c+=dist[ed]*Min;
            f+=Min;
        }
    }
    int order[maxn][maxn];
    int supply[maxn][maxn];
    int tolorder[maxn];
    int main() {
        int N,M;
        int K;
        while(scanf("%d%d%d",&N,&M,&K)!=EOF) {
            if(N==0&&M==0&&K==0)break;
            st=0;
            n=N+M+1;
            ed=n;
            memset(cap,0,sizeof(cap));
            memset(cost,0,sizeof(cost));
            for(int i=0;i<N;i++)
            for(int j=0;j<K;j++)
            scanf("%d",&order[i][j]);
            for(int i=0;i<M;i++)
            for(int j=0;j<K;j++)
            scanf("%d",&supply[i][j]);
            for(int i=0;i<K;i++) {
                tolorder[i]=0;
                for(int j=0;j<N;j++)
                tolorder[i]+=order[j][i];
            }
            for(int i=1;i<=M;i++)
            for(int j=M+1;j<=N+M;j++)
            cap[i][j]=inf;
            bool flag=true;
            int ans=0;
            for(int i=0;i<K;i++) {
                for(int j=M+1;j<=M+N;j++)
                for(int k=1;k<=M;k++) {
                    scanf("%d",&cost[k][j]);
                    cost[j][k]=-cost[k][j];
                }
                if(!flag)continue;
                for(int j=1;j<=M;j++)
                cap[st][j]=supply[j-1][i];
                for(int j=1;j<=N;j++)
                cap[j+M][ed]=order[j-1][i];
                minCostMaxflow();
                if(f<tolorder[i])flag=false;
                else ans+=c;
            }
            if(!flag)printf("-1
    ");
            else printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    【学习小记】一般图最大匹配——带花树算法
    如何检查oracle的归档空间是否满了
    Linux 的计划任务
    转 oracle的热备份和冷备份
    SQLException: Io 异常: Connection refused ERR=12514 ERR=1153异常处理过程
    查看oracle数据库版本
    ORACLE默认实例设置--linux
    oracle查看用户属于哪个表空间
    oracle默认数据库实例
    oracle 查看用户所在的表空间
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12316412.html
Copyright © 2020-2023  润新知