POJ 2516 Minimum Cost (费用流)

Posted kongbursi-2292702937

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

 

以上是关于POJ 2516 Minimum Cost (费用流)的主要内容,如果未能解决你的问题,请参考以下文章

POJ2516 Minimum Cost最小费用最大流

POJ 2516 Minimum Cost (最小费用最大流)

POJ 2516:Minimum Cost(最小费用流)

POJ-2516 Minimum Cost(最小费用最大流)

Minimum Cost POJ - 2516 (模板题 spfa最小费用最大流)

POJ 2516 Minimum Cost (费用流)