zoukankan      html  css  js  c++  java
  • 【费用流】【网络流24题】【cogs 739】运输问题

    739. [网络流24题] 运输问题

    ★★   输入文件:tran.in   输出文件:tran.out   简单对照
    时间限制:1 s   内存限制:128 MB
    

    «问题描写叙述:

    这里写图片描写叙述

    «编程任务:

    对于给定的m 个仓库和n 个零售商店间运送货物的费用,计算最优运输方案和最差运输方案。

    «数据输入:

    这里写图片描写叙述

    «结果输出:

    程序执行结束时,将计算出的最少运输费用和最多运输费用输出到文件tran.out中。

    输入文件演示样例 输出文件演示样例
    tran.in

    2 3
    220 280
    170 120 210
    77 39 105
    150 186 122
    

    tran.out

    48500
    69140
    

    对于全部数据:1<=N,M<=100

    题解:
    比較easy想到费用流。
    建图:
    1>建立虚拟源S和汇T。
    2>从S到m个仓库建流量为a[i],费用为0的边。


    3>从n个商店向T建流量为b[i],费用为0的边。
    4>从m个仓库向n个商店建流量为无穷大。费用为c[i][j]的边。
    然后跑一边最小费用。再跑一边最大费用就好了。

    Code:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define N 310
    #define M 30010
    #define inf 0x7ffffff
    using namespace std;
    struct Edge{
        int v,next,cap,cost;
    }edge[M];
    int n,m,num,ans,S,T,a[N],b[N],c[N][N];
    int head[N],flow[N],prep[N],prev[N],dis[N],q[M];
    bool vis[N];
    int in(){
        int x=0; char ch=getchar();
        while (ch<'0' || ch>'9') ch=getchar();
        while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return x;
    }
    void add(int u,int v,int cap,int cost){
        edge[++num].v=v; edge[num].next=head[u]; head[u]=num;
        edge[num].cap=cap; edge[num].cost=cost;
    }
    void build(){
        S=0,T=m+n+1;
        for (int i=1; i<=m; i++)
            add(S,i,a[i],0),add(i,S,0,0);
        for (int i=1; i<=n; i++)
            add(i+m,T,b[i],0),add(T,i+m,0,0);
        for (int i=1; i<=m; i++)
            for (int j=1; j<=n; j++)
                add(i,j+m,inf,c[i][j]),add(j+m,i,0,-c[i][j]);
    }
    bool spfa(int k){
        int h=0,t=1;
        if (k>0) memset(dis,0x3f,sizeof(dis));
        else memset(dis,128,sizeof(dis));
        memset(vis,0,sizeof(vis));
        dis[S]=0; q[h]=S; vis[S]=1;
        flow[S]=inf; prep[S]=-1;
        while (h<t){
            int u=q[h++]; vis[u]=0;
            for (int i=head[u]; i; i=edge[i].next){
                int v=edge[i].v;
                if (edge[i].cap>0 && ((k>0 && dis[v]>dis[u]+edge[i].cost) || (k<0 && dis[v]<dis[u]+edge[i].cost))){
                    dis[v]=dis[u]+edge[i].cost;
                    prep[v]=u; prev[v]=i;
                    flow[v]=min(flow[u],edge[i].cap);
                    if (!vis[v]) vis[v]=1,q[t++]=v;
                }
            }
        }
        if (k>0){
            if (dis[T]>inf) return 0;
            else return 1;
        }
        else {
            if (dis[T]<0) return 0;
            else return 1;
        }
    }
    void work(){
        for (int i=T; i!=S; i=prep[i]){
            edge[prev[i]].cap-=flow[T];
            edge[prev[i]^1].cap+=flow[T];
        }
        ans+=flow[T]*dis[T];
    }
    int main(){
        m=in(),n=in();
        for (int i=1; i<=m; i++) a[i]=in();
        for (int i=1; i<=n; i++) b[i]=in();
        for (int i=1; i<=m; i++)
            for (int j=1; j<=n; j++) c[i][j]=in();
        num=1; build(); ans=0;
        while (spfa(1)) work();
        printf("%d
    ",ans);
        memset(head,0,sizeof(head));
        memset(prep,0,sizeof(prep));
        memset(prev,0,sizeof(prev));
        memset(flow,0,sizeof(flow));
        num=1; build(); ans=0;
        while (spfa(-1)) work();
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    实现第三方系统单点登录
    python爬虫
    webot设备motor的api
    webots学习
    python学习算术运算
    python快捷键与命令函数
    python学习构造和析构
    python学习对象相关的bif
    python学习对象:拾遗
    matlab基础知识
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5348261.html
Copyright © 2011-2022 走看看