• 【网络流24题】运输问题(费用流)(网络费用流量)


    【网络流24题】运输问题

    题目描述 Description

    W 公司有m个仓库和n 个零售商店。第i 个仓库有ai 个单位的货物;第j 个零售商店
    需要bj个单位的货物。货物供需平衡,即  sum(si)=sum(bj)
    。从第i 个仓库运送每单位货物到
    第j 个零售商店的费用为cij 。试设计一个将仓库中所有货物运送到零售商店的运输方案,
    使总运输费用最少。
    编程任务:
    对于给定的m 个仓库和n 个零售商店间运送货物的费用,计算最优运输方案和最差运输方案。

    输入描述 Input Description

    的第1行有2 个正整数m和n,分别表示仓库数和
    零售商店数。接下来的一行中有m个正整数ai ,1≤i≤m,表示第i个仓库有ai 个单位的货
    物。再接下来的一行中有n个正整数bj ,1≤j≤n,表示第j个零售商店需要bj 个单位的货
    物。接下来的m行,每行有n个整数,表示从第i 个仓库运送每单位货物到第j个零售商店
    的费用cij 。

    输出描述 Output Description

    将计算出的最少运输费用和最多运输费用输出

    样例输入 Sample Input

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

    样例输出 Sample Output

    48500
    69140

    一道水题,网络流24题需要吐槽了,上下界的网络流没有

    跑得挺快的。

    很好构图,就是S向左边的点,连ai个单位,费用为0,右边向T连bi个单位,费用为0

    然后左边向右边流量无限,费用c[i][j],即可,hh。

      1 #include<cstring>
      2 #include<cmath>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<cstdio>
      6 #include<queue>
      7 
      8 #define N 2007
      9 #define M 1000007
     10 #define inf 1000000007
     11 using namespace std;
     12 inline int read()
     13 {
     14     int x=0,f=1;char ch=getchar();
     15     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
     16     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     17     return x*f;
     18 }
     19 
     20 int m,n,S,T;
     21 int cnt=1,head[N],next[M],rea[M],val[M],cost[M];
     22 int c[N][N],a[N],b[N];
     23 int dis[N],flag[N];
     24 struct Node
     25 {
     26     int e,fa;
     27     void init(){e=fa=-1;}
     28 }pre[N];
     29 
     30 void add(int u,int v,int fee,int pay)
     31 {
     32     next[++cnt]=head[u];
     33     head[u]=cnt;
     34     rea[cnt]=v;
     35     val[cnt]=fee;
     36     cost[cnt]=pay;
     37 }
     38 void build(int k)
     39 {
     40     memset(head,-1,sizeof(head));cnt=1;
     41     for (int i=1;i<=m;i++)
     42     {
     43         int x=a[i];
     44         add(S,i,x,0),add(i,S,0,0);
     45     }
     46     for (int i=1;i<=n;i++)
     47     {
     48         int x=b[i];
     49         add(m+i,T,x,0),add(T,m+i,0,0);
     50     }
     51     for (int i=1;i<=m;i++)
     52         for (int j=1;j<=n;j++)
     53         {
     54             int x=c[i][j];
     55             add(i,m+j,inf,x*k),add(m+j,i,0,-x*k);
     56         }
     57 }
     58 bool Spfa()
     59 {
     60     for (int i=S;i<=T;i++)
     61         dis[i]=inf,flag[i]=0,pre[i].init();
     62     queue<int>q;q.push(S);
     63     dis[S]=0,flag[S]=1;
     64     while(!q.empty())
     65     {
     66         int u=q.front();q.pop();
     67         for (int i=head[u];i!=-1;i=next[i])
     68         {
     69             int v=rea[i],fee=cost[i];
     70             if ((dis[v]>dis[u]+fee)&&val[i]>0)
     71             {
     72                 dis[v]=dis[u]+fee;
     73                 pre[v].e=i,pre[v].fa=u;
     74                 if (!flag[v])
     75                 {
     76                     flag[v]=1;
     77                     q.push(v);
     78                 }
     79             }
     80         }    
     81         flag[u]=0;
     82     }
     83     if (dis[T]==inf) return 0;
     84     else return 1;
     85 }
     86 int mfmc()
     87 {
     88     int flow=0,res=0;
     89     while(Spfa())
     90     {
     91         int x=inf;
     92         for (int i=T;pre[i].fa!=-1;i=pre[i].fa)
     93         {
     94             int e=pre[i].e;
     95             x=min(x,val[e]);
     96         }
     97         flow+=x,res+=dis[T]*x;
     98         for (int i=T;pre[i].fa!=-1;i=pre[i].fa)
     99         {
    100             int e=pre[i].e;
    101             val[e]-=x,val[e^1]+=x;
    102         }
    103     }
    104     return res;
    105 }
    106 int main()
    107 {
    108     m=read(),n=read();S=0,T=n+m+1;
    109     for (int i=1;i<=m;i++) a[i]=read();
    110     for (int i=1;i<=n;i++) b[i]=read();
    111     for (int i=1;i<=m;i++)
    112         for (int j=1;j<=n;j++)
    113             c[i][j]=read();
    114     build(1);
    115     printf("%d
    ",mfmc());
    116     build(-1);
    117     printf("%d
    ",-mfmc());
    118 }
  • 相关阅读:
    【牛客网】Finding Hotel
    【牛客网】Longest Common Subsequence
    【ZOJ】4012 Your Bridge is under Attack
    【LOJ】#2210. 「HNOI2014」江南乐
    可能是一篇(抄来的)min25学习笔记
    【LOJ】#3020. 「CQOI2017」小 Q 的表格
    【51nod】1602 矩阵方程的解
    【51nod】1634 刚体图
    【51nod】1407 与与与与
    【51nod】1776 路径计数
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7931583.html
Copyright © 2020-2023  润新知