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

     
    第一行是三个数字:N,M,K
    分别表示有N个商店,M个供货商,K中货物
    接下来是N行,每行K个整数
    对于第i行第j列,表示的是第i个商店对于货物j的需求
    再接着,M行,每行K个整数
    对于第i行第j列,表示的是第i个供货商对于货物j的存货
    接下来有K个N*M的矩形
    第X个矩形的第i行第j列表示的是
    从供货商j 运送一个单位的 货物X 到商店i的 花费
    最后要求的是
    在满足 所有商店的供应的 情况下的 最小花费
    如果无法满足,则输出-1
    题解:
    首先弄清楚题目的意思
    考虑k种货物都是独立的,因此只需要考虑k遍最小的费用然后求和
    对于每一次的最小费用,显然直接求解最小费用流即可,
    对于图的构建并不难,
    但是要考虑清楚每条边的容量
    从汇点向每个供货商连接一条容量为存货数量,费用为0的边
    然后从每个供货商向每个商店连接一条容量为INF,费用为花费的边(容量连接成存货数量也行)
    从商店向汇点连接一条容量为需求,费用为0的边
    求解K次最小费用流累加答案即可。

    参考链接:https://blog.csdn.net/qq_30974369/article/details/76648579
     
    代码:
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <queue>
      5 #include <cmath>
      6 using namespace std;
      7 const int maxn = 210;
      8 const int maxm = 1000;
      9 const int INF = 0x3f3f3f3f;
     10 struct edge
     11 {
     12     int v, next, cap, flow, cost;
     13     int x, y;
     14 } e[maxn*maxn];
     15 struct shudui
     16 {
     17     int s[55];
     18 }p1[55],p2[55];
     19 int c[55][55][55];
     20 int head[maxn],tol;
     21 int pre[maxn],dis[maxn];
     22 bool vis[maxn];
     23 void init()
     24 {
     25     tol = 0;
     26     memset(head, -1, sizeof(head));
     27 }
     28 void add_edge(int x,int y,int cap,int cost)
     29 {
     30     e[tol].v=y;
     31     e[tol].cap=cap;
     32     e[tol].flow=0;
     33     e[tol].cost=cost;
     34     e[tol].next=head[x];
     35     head[x]=tol++;
     36 
     37     e[tol].v=x;
     38     e[tol].cap=0;
     39     e[tol].flow=0;
     40     e[tol].cost=-cost;
     41     e[tol].next=head[y];
     42     head[y]=tol++;
     43 }
     44 int spfa(int s,int t)
     45 {
     46     queue<int>r;
     47     for(int i=0;i<maxn;++i)
     48     {
     49         vis[i]=0;
     50         dis[i]=INF;
     51         pre[i]=-1;
     52     }
     53     dis[s]=0;
     54     vis[s]=1;
     55     r.push(s);
     56     while(!r.empty())
     57     {
     58 
     59         int u=r.front();
     60         r.pop();
     61         vis[u]=0;
     62         for(int i=head[u];i!=-1;i=e[i].next)
     63         {
     64             int v=e[i].v;
     65             if(e[i].cap>e[i].flow && dis[v]>dis[u]+e[i].cost)
     66             {
     67                 dis[v]=dis[u]+e[i].cost;
     68                 pre[v]=i;
     69                 if(!vis[v])
     70                 {
     71                     vis[v]=1;
     72                     r.push(v);
     73                 }
     74             }
     75         }
     76     }
     77     if(pre[t]==-1) return 0;
     78     else return 1;
     79 }
     80 int MincostMaxflow(int s,int t,int &cost)
     81 {
     82     int flow=0;
     83     cost=0;
     84     while(spfa(s,t))
     85     {
     86         int minn=INF;
     87         for(int i=pre[t];i!=-1;i=pre[e[i^1].v])
     88         {
     89             if(minn>e[i].cap-e[i].flow)
     90             {
     91                 minn=e[i].cap-e[i].flow;
     92             }
     93         }
     94         for(int i=pre[t];i!=-1;i=pre[e[i^1].v])
     95         {
     96             e[i].flow+=minn;
     97             e[i^1].flow-=minn;
     98             cost+=e[i].cost*minn;
     99         }
    100         flow+=minn;
    101     }
    102     return flow;
    103 }
    104 
    105 int main()
    106 {
    107     int n,m,k,st,en;
    108     char s[105][105];
    109     while(~scanf("%d%d%d",&n,&m,&k) && n+m+k)
    110     {
    111         for(int i=1;i<=n;++i)
    112         {
    113             for(int j=1;j<=k;++j)
    114                 scanf("%d",&p1[i].s[j]);
    115         }
    116         for(int i=1;i<=m;++i)
    117         {
    118             for(int j=1;j<=k;++j)
    119                 scanf("%d",&p2[i].s[j]);
    120         }
    121         for(int ii=1;ii<=k;++ii)
    122         {
    123             for(int i=1;i<=n;++i)
    124             {
    125                 for(int j=1;j<=m;++j)
    126                 {
    127                     scanf("%d",&c[ii][i][j]);
    128                 }
    129             }
    130         }
    131         st=0;
    132         en=n+m+1;
    133         int sum=0,flag=0;
    134 
    135         for(int ii=1;ii<=k;++ii)
    136         {
    137             init();
    138             int ans1=0,ans2=0;
    139             for(int i=1;i<=n;++i)
    140             {
    141                 add_edge(st,i,p1[i].s[ii],0);
    142                 ans1+=p1[i].s[ii];
    143             }
    144             for(int i=1;i<=n;++i)
    145             {
    146                 for(int j=1;j<=m;++j)
    147                 {
    148                     add_edge(i,n+j,INF,c[ii][i][j]);
    149                 }
    150             }
    151             for(int i=1;i<=m;++i)
    152             {
    153                 add_edge(n+i,en,p2[i].s[ii],0);
    154                 ans2+=p2[i].s[ii];
    155             }
    156             if(ans1>ans2)
    157             {
    158                 flag=1;
    159                 break;
    160             }
    161             int ans=0;
    162             MincostMaxflow(st,en,ans);
    163             sum+=ans;
    164             //printf("-----------------
    ");
    165         }
    166         if(flag)
    167             printf("-1
    ");
    168         else
    169             printf("%d
    ",sum);
    170     }
    171     return 0;
    172 }
    View Code
  • 相关阅读:
    《Java程序设计》第七次学习总结
    《Java程序设计》第六次学习总结
    实验二:Java面向对象程序设计
    《信息安全系统设计基础》第二次学习总结
    《信息安全系统设计基础+Linux 内核分析》第一次学习总结
    《Java程序设计》第五次学习总结
    《Java程序设计》第四次学习总结
    《Java程序设计》第三次学习总结
    next_permutation 函数
    POJ 3268 (dijkstra算法)
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11838012.html
Copyright © 2011-2022 走看看