zoukankan      html  css  js  c++  java
  • poj 2516 Minimum Cost (最小费用流 )

    题意:有N个客户,M个仓库,和K种货物。已知每个客户需要每种货物的数量,每个仓库存储每种货物的数量,每个仓库运输各种货物去各个客户的单位费用。判断所有的仓库能否满足所有客户的需求,如果可以,求出最少的运输总费用。

     

    思路:最小费用最大流。先判断是否每种货物的存储总量都足够,足够的话,对每一种货物进行一次最小费用最大流求出完成这种货物运输的最小总费用,所有的总费用相加就是结果了。

     

    思路:最小费用最大流。先判断是否每种货物的存储总量都足够,

         足够的话,对每一种货物进行一次最小费用最大  流求出完成这种货物运输的最小总费用,所有的总费用相加就是结果了。

      http://poj.org/problem?id=2516

      1 #include<stdio.h>
      2 #define maxn 200
      3 #define inf 0x7fffffff
      4 #include<string.h>
      5 int  need[maxn][maxn],needk[maxn],have[maxn][maxn],havek[maxn],cap[maxn][maxn],map[maxn][maxn];
      6 int que[maxn],ans,pre[maxn];
      7 int n,m,k,max;
      8 int dis[maxn],vis[maxn];
      9 int min(int x,int y)
     10 {
     11     if(x<y)return x;
     12     else  return y;
     13 }
     14 int SPFA()
     15 {
     16     int i,head=0,tail=0;
     17     for(i=0;i<=max;i++)
     18     {
     19         dis[i]=inf;
     20         vis[i]=0;
     21     }
     22     dis[0]=0;
     23     vis[0]=1;
     24     que[head]=0;
     25     tail++;
     26     while(head!=tail)
     27     {
     28 
     29         int u=que[head];
     30         vis[u]=0;
     31         for(i=0;i<=max;i++)
     32         {
     33             if(cap[u][i]&&dis[i]>dis[u]+map[u][i])
     34             {
     35 
     36                 dis[i]=dis[u]+map[u][i];
     37                 pre[i]=u;
     38                 if(!vis[i])
     39                 {
     40                     vis[i]=1;
     41                     que[tail++]=i;
     42                     if(tail==maxn)tail=0;
     43                 }
     44             }
     45         }
     46         head++;
     47         if(head==maxn)head=0;
     48     }
     49     if(dis[max]==inf)return 0;
     50     else return 1;
     51 }
     52 void Update()
     53 {
     54     int i,sum=inf;
     55     for(i=max;i!=0;i=pre[i])
     56     {
     57         sum=min(sum,cap[pre[i]][i]);//寻找(最短)增广路经上的最小 流量
     58     }
     59 
     60     for(i=max;i!=0;i=pre[i])
     61     {
     62         cap[pre[i]][i]-=sum;
     63         cap[i][pre[i]]+=sum;
     64         ans+=map[pre[i]][i]*sum;
     65 
     66     }
     67 
     68 }
     69 int main()
     70 {
     71     int i,j,l;
     72   while(scanf("%d%d%d",&n,&m,&k)!=EOF)
     73   {
     74       if(n==0&&m==0&&k==0)break;
     75       memset(needk,0,sizeof(needk));
     76       memset(havek,0,sizeof(havek));
     77       for(i=1;i<=n;i++)
     78       {
     79           for(j=1;j<=k;j++)
     80           {
     81               scanf("%d",&need[i][j]);
     82               needk[j]+=need[i][j];
     83           }
     84       }
     85 
     86       for(i=1;i<=m;i++)
     87       {
     88           for(j=1;j<=k;j++)
     89           {
     90               scanf("%d",&have[i][j]);
     91               havek[j]+=have[i][j];
     92           }
     93       }
     94       int f=0;
     95       ans=0;
     96       for(i=1;i<=k;i++)
     97       {
     98           if(needk[i]>havek[i])
     99           {
    100               f=1;
    101               break;
    102           }
    103       }
    104 
    105       max=n+m+1;
    106       for(i=1;i<=k;i++)
    107       {
    108           memset(cap,0,sizeof(cap));
    109           for(j=1;j<=n;j++)
    110           {
    111               for(l=1;l<=m;l++)
    112               {
    113                   scanf("%d",&map[l][j+m]);
    114                   map[j+m][l]=-map[l][j+m];
    115                   cap[l][j+m]=inf;
    116 
    117               }
    118           }
    119 
    120           for(j=1;j<=m;j++)
    121           {
    122               cap[0][j]=have[j][i];
    123               map[0][j]=map[j][0]=0;
    124 
    125           }
    126           for(j=1;j<=n;j++)
    127           {
    128               cap[j+m][max]=need[j][i];
    129               map[j+m][max]=map[max][j+m]=0;
    130           }
    131 
    132           while(SPFA())Update();//最小费用算法
    133 
    134       }
    135       if(!f)printf("%d\n",ans);
    136       else printf("-1\n");
    137   }
    138 }
  • 相关阅读:
    成为一个优秀的C++程序员
    C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast
    C++经典类库(C++开发必看)
    auto_ptr, unique_ptr, shared_ptr and weak_ptr智能指针讲解
    C++ clone()函数的用法
    c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast
    C++模板详解(转)
    static变量的作用(转)
    2018年12月17日,新工作,可是一点提不起兴趣,在原点转啊转,园子什么时候会关了呢,我们终将老去
    给C#Control组件统一增加加属性
  • 原文地址:https://www.cnblogs.com/acSzz/p/2481347.html
Copyright © 2011-2022 走看看