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

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <queue>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <cstring>
      7 using namespace std;
      8 
      9 #define inf 0x3f3f3f3f
     10 
     11 int supply[55],demand[55];//某种商品的提供量和需求量
     12 int dis[110],pre[110],s,t;//s为超级源点,t为超级汇点
     13 int order[55][55];//第i个商店对第j种物品的需求
     14 int store[55][55];//第i个供应站对第j个物品的存储量
     15 int flow[110][110],cap[110][110];//边的流量,容量
     16 int cost[55][55][55];//cost[k][j][i]第k种商品从第j个供应站运到第i个商店的花费
     17 int kcost[110][110];//每件商品在某一条边的花费。从供应站到商店方向
     18 int vis[110];
     19 int n,m,k;
     20 
     21 int spfa()
     22 {
     23     queue<int>q;
     24     memset(vis,0,sizeof(vis));
     25     memset(pre,-1,sizeof(pre));
     26     q.push(s);
     27     fill(&dis[1],&dis[n+m+2],inf);//dis[1----n+m+1]==inf
     28     dis[s]=0;
     29     vis[s]=1;
     30     while(!q.empty())
     31     {
     32         int cur=q.front();q.pop();
     33         vis[cur]=0;
     34         for(int i=0;i<=n+m+1;i++)
     35         {
     36             if(cap[cur][i] >flow[cur][i] && dis[i] > dis[cur] + kcost[cur][i])
     37             {
     38                 dis[i]=dis[cur]+kcost[cur][i];
     39                 pre[i]=cur;
     40                 if(!vis[i])
     41                 {
     42                     vis[i]=1;
     43                     q.push(i);
     44                 }
     45             }
     46         }
     47     }
     48     return pre[t]!=-1;//pre[t]==-1表示无增广路
     49 }
     50 
     51 void costflow()
     52 {
     53     int minf=inf;
     54     while(spfa())
     55     {
     56         for(int u=t;pre[u] != -1;u=pre[u])
     57         {
     58             minf=min(minf,cap[pre[u]][u]-flow[pre[u]][u]);
     59         }
     60         for(int u=t;pre[u] !=-1 ;u=pre[u])//沿着最小费用路进行增广
     61         {
     62             flow[pre[u]][u]+=minf;
     63             flow[u][pre[u]]-=minf;
     64         }
     65     }
     66 }
     67 
     68 int main()
     69 {
     70     while(scanf("%d%d%d",&n,&m,&k))
     71     {
     72         if(!n && !m && !k) break;
     73         int flag=1;//判断是否无解
     74         memset(supply,0,sizeof(supply));
     75         memset(demand,0,sizeof(demand));
     76         for(int i=1;i<=n;i++)
     77         {
     78             for(int j=1;j<=k;j++)
     79             {
     80                 scanf("%d",&order[i][j]);
     81                 demand[j]+=order[i][j];
     82             }
     83         }
     84         for(int i=1;i<=m;i++)
     85         {
     86             for(int j=1;j<=k;j++)
     87             {
     88                 scanf("%d",&store[i][j]);
     89                 supply[j]+=store[i][j];
     90             }
     91         }
     92         for(int p=1;p<=k;p++)
     93         {
     94             for(int i=1;i<=n;i++)
     95             {
     96                 for(int j=1;j<=m;j++)
     97                 {
     98                     scanf("%d",&cost[p][j][i]);
     99                 }
    100             }
    101         }
    102         for(int i=1;i<=k;i++)
    103         {
    104             if(demand[i]>supply[i])
    105             {
    106                 flag=0;
    107                 break;
    108             }
    109         }
    110         int flowcost=-1;
    111         if(flag)
    112         {
    113             s=0;
    114             t=n+m+1;
    115             //按照商品数构图k次
    116             //cap,kcost,下标1----m为供应站,m+1--m+n为商店
    117             flowcost=0;
    118             for(int p=1;p<=k;p++)
    119             {
    120                 memset(cap,0,sizeof(cap));
    121                 memset(kcost,0,sizeof(kcost));
    122                 memset(flow,0,sizeof(flow));
    123                 for(int i=1;i<=m;i++)//源点到供应站建边
    124                     cap[s][i]=store[i][p];
    125                 for(int i=1;i<=n;i++)
    126                     cap[i+m][t]=order[i][p];
    127                 for(int i=1;i<=m;i++)
    128                 {
    129                     for(int j=1;j<=n;j++)
    130                     {
    131                         cap[i][j+m]=store[i][p];
    132                         kcost[i][j+m]=cost[p][i][j];
    133                         kcost[j+m][i]=-cost[p][i][j];//负费用,表示回流费用增加
    134                     }
    135                 }
    136                 costflow();
    137                 for(int i=1;i<=m;i++)
    138                 {
    139                     for(int j=1;j<=n;j++)
    140                         flowcost+=kcost[i][j+m]*flow[i][j+m];//单价乘流量
    141                 }
    142             }
    143         }
    144         printf("%d\n",flowcost);
    145     }
    146     return 0;
    147 }
  • 相关阅读:
    新克隆环境无法创建供应商,报供应商名称已存在
    批处理学习:for语句详解【经典】(转)
    信号与槽引用传递
    串口封装
    tcp客户端封装
    qt无法定位程序输入点 于动态链接库 qt5core.dll
    对象new和不new的理解
    Qt重绘机制
    红绿灯
    获取所有子控件
  • 原文地址:https://www.cnblogs.com/Missa/p/2802395.html
Copyright © 2011-2022 走看看