• 网络流24题-运输问题(费用流)


    题目描述

    WW 公司有 mm 个仓库和 nn 个零售商店。第 ii 个仓库有 a_iai 个单位的货物;第 jj 个零售商店需要 b_jbj 个单位的货物。

    货物供需平衡,即sumlimits_{i=1}^{m}a_i=sumlimits_{j=1}^{n}b_ji=1mai=j=1nbj

    从第 ii 个仓库运送每单位货物到第 jj 个零售商店的费用为 c_{ij}cij​​ 。

    试设计一个将仓库中所有货物运送到零售商店的运输方案,使总运输费用最少。

    输入输出格式

    输入格式:

    第 11 行有 22 个正整数 mm 和 nn,分别表示仓库数和零售商店数。

    接下来的一行中有 mm 个正整数 a_iai,表示第 ii 个仓库有 a_iai个单位的货物。

    再接下来的一行中有 nn 个正整数 b_jbj,表示第 jj 个零售商店需要 b_jbj 个单位的货物。

    接下来的 mm 行,每行有 nn 个整数,表示从第 ii 个仓库运送每单位货物到第 jj 个零售商店的费用 c_{ij}cij

    输出格式:

    两行分别输出最小运输费用和最大运输费用。

    输入输出样例

    输入样例
    2 3
    220 280
    170 120 210
    77 39 105
    150 186 122
    输出样例
    48500
    69140

    说明

    1n,m100

    求最小费用直接套模板,最大费用取相反数,结果也取相反数即可

    **模板来自kuangbin

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int inf=0x3f3f3f3f;
      4 const int MAXN=10000;//点的总数
      5 const int MAXM=100000;//边的总数
      6 struct Edge{
      7     int to,nxt,cap,flow,cost;
      8 }edge[MAXM];
      9 int head[MAXN],tot;
     10 int pre[MAXN],dis[MAXN];
     11 bool vis[MAXN];
     12 int N;//节点总个数,节点编号0~N-1
     13 void init()
     14 {
     15     tot=0;
     16     memset(head,-1,sizeof(head));
     17 }
     18 void addedge(int u,int v,int cap,int cost)
     19 {
     20     edge[tot].to=v;     edge[tot].cap=cap;   edge[tot].cost=cost;
     21     edge[tot].flow=0;   edge[tot].nxt=head[u];  head[u]=tot++;
     22 
     23     edge[tot].to=u;     edge[tot].cap=0;    edge[tot].cost=-cost;
     24     edge[tot].flow=0;    edge[tot].nxt=head[v];     head[v]=tot++;
     25 }
     26 bool spfa(int s,int t)
     27 {
     28     queue<int>q;
     29     for(int i=0;i<N;i++)
     30     {
     31         dis[i]=inf;
     32         vis[i]=false;
     33         pre[i]=-1;
     34     }
     35     dis[s]=0;
     36     vis[s]=true;
     37     q.push(s);
     38     while(!q.empty())
     39     {
     40         int u=q.front();    q.pop();
     41         vis[u]=false;
     42         for(int i=head[u];i!=-1;i=edge[i].nxt)
     43         {
     44             int v=edge[i].to;
     45             if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost)
     46             {
     47                 dis[v]=dis[u]+edge[i].cost;
     48                 pre[v]=i;
     49                 if(!vis[v])
     50                 {
     51                     vis[v]=true;
     52                     q.push(v);
     53                 }
     54             }
     55         }
     56     }
     57     if(pre[t]==-1)  return false;
     58     else            return true;
     59 }
     60 int MCMF(int s,int t,int &cost)
     61 {
     62     int flow=0;
     63     cost=0;
     64     while(spfa(s,t))
     65     {
     66         int minn=inf;
     67         for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
     68         {
     69             if(minn>edge[i].cap-edge[i].flow)
     70                 minn=edge[i].cap-edge[i].flow;
     71         }
     72         for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
     73         {
     74             edge[i].flow+=minn;
     75             edge[i^1].flow-=minn;
     76             cost+=edge[i].cost*minn;
     77         }
     78         flow+=minn;
     79     }
     80     return flow;
     81 }
     82 int c[200][200],a[200],b[200];
     83 int main()
     84 {
     85     ios::sync_with_stdio(false);
     86     cin.tie(0);cout.tie(0);
     87     int n,m;
     88     cin>>n>>m;
     89     int s=0,t=n+m+1;
     90     N=t+1;
     91     init();
     92     for(int i=1;i<=n;i++)
     93     {
     94         cin>>a[i];
     95         addedge(s,i,a[i],0);
     96     }
     97     for(int i=1;i<=m;i++)
     98     {
     99         cin>>b[i];
    100         addedge(i+n,t,b[i],0);
    101     }
    102     for(int i=1;i<=n;i++)
    103     {
    104         for(int j=1;j<=m;j++)
    105         {
    106             cin>>c[i][j];
    107             addedge(i,j+n,inf,c[i][j]);
    108         }
    109     }
    110     int cost=0;
    111     MCMF(s,t,cost);
    112     cout<<cost<<endl;
    113     init();
    114     for(int i=1;i<=n;i++)   addedge(s,i,a[i],0);
    115     for(int i=1;i<=m;i++)   addedge(i+n,t,b[i],0);
    116     for(int i=1;i<=n;i++)
    117     {
    118         for(int j=1;j<=m;j++)
    119         {
    120             addedge(i,j+n,inf,-c[i][j]);
    121         }
    122     }
    123     cost=0;
    124     MCMF(s,t,cost);
    125     cout<<-cost<<endl;
    126     return 0;
    127 }
    如有错误,请指正,感谢!
  • 相关阅读:
    精通正则表达式(JavaScript)
    Go知识点记录
    多线程揭秘
    Python test
    ELinq+T4模版引擎制作多文件实体代码生成器
    浏览器内核
    MongoDb的增删改查
    LINQ执行表达式
    ASP.NET MVC3 读书笔记四(数据注解和验证)
    C#默认以管理员身份运行程序
  • 原文地址:https://www.cnblogs.com/scott527407973/p/9861379.html
Copyright © 2020-2023  润新知