题意:

从发货地到商家 送货 求送货花费的最小费用。。。

有m个发货地,,,n个商家,,每个商家所需要的物品和物品的个数都不一样,,,每个发货地有的物品和物品的个数也不一样,,,

从不同的发货地到不同的商家 送不同的物品 所花费的价钱 也不一样。。

解析;

建立超级源s和超级汇t

因为每个商家所需的每个物品的数量都不一样,,,所以我们要分物品来进行最小费用最大流

在最外面一个循环,遍历每一个物品,,,然后对于当前物品建图

把每个发货地和s连边 权值为每个发货地所拥有的当前物品的数量,,,花费0

把商家个t连边,, 权值为每个商家所需要的当前物品的数量,,花费0

然后 发货地和商家连边。。。权值为INF,  花费为每个发货地到每个商家对于当前物品所对应的花费

这是一个对象所需不同物品的个数不一样的题

贴一个对象所需不同物品的个数一样的题:https://www.cnblogs.com/WTSRUVF/p/9202751.html

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn = , INF = 0x7fffffff;
typedef long long LL;
int head[maxn], d[maxn], vis[maxn], p[maxn], f[maxn];
int frome[maxn], to[maxn], ca[][][];
int needs[][], have[][];
int n, m, s, t, k;
int cnt, flow, value; struct node{
int u, v, c, w, next;
}Node[maxn]; void add_(int u, int v, int c, int w)
{
Node[cnt].u = u;
Node[cnt].v = v;
Node[cnt].c = c;
Node[cnt].w = w;
Node[cnt].next = head[u];
head[u] = cnt++;
} void add(int u, int v, int c, int w)
{
add_(u, v, c, w);
add_(v, u, ,-w);
} int spfa()
{
queue<int> Q;
for(int i=; i<maxn; i++) d[i] = INF;
mem(vis, );
mem(p, -);
Q.push(s);
d[s] = ;
vis[s] = ;
p[s] = ; f[s] = INF;
while(!Q.empty())
{
int u = Q.front(); Q.pop();
vis[u] = ;
for(int i=head[u]; i!=-; i=Node[i].next)
{
node e = Node[i];
if(d[e.v] > d[e.u] + e.w && e.c > )
{
d[e.v] = d[e.u] + e.w;
p[e.v] = i;
f[e.v] = min(f[u], e.c);
if(!vis[e.v])
{
Q.push(e.v);
vis[e.v] = ;
}
}
}
}
if(p[t] == -) return ;
flow += f[t]; value += f[t]* d[t];
for(int i=t; i!=s; i=Node[p[i]].u)
{
Node[p[i]].c -= f[t];
Node[p[i]^].c += f[t];
}
return ;
} int max_flow()
{
value = ;
flow = ;
while(spfa());
return value;
} int main()
{
while(~scanf("%d%d%d",&n,&m,&k) && n+m+k)
{
int ret = ;
int ok = ;
s = , t = (n+m)*+;
mem(head, -);
mem(frome, );
mem(to, );
cnt = ;
for(int i=; i<=n; i++)
for(int j=; j<=k; j++)
{
scanf("%d",&needs[i][j]);
frome[j] += needs[i][j];
}
for(int i=; i<=m; i++)
for(int j=; j<=k; j++)
{
scanf("%d",&have[i][j]);
to[j] += have[i][j];
}
for(int i=; i<=k; i++)
for(int j=; j<=n; j++)
for(int l=; l<=m; l++)
scanf("%d",&ca[i][j][l]); for(int i=; i<=k; i++)
{
if(frome[i] > to[i])
{
printf("-1\n");
ok = ;
break;
}
}
if(!ok) continue;
for(int i=; i<=k; i++)
{
mem(head, -);
cnt = ; for(int j=; j<=n; j++)
add(j, t, needs[j][i], );
for(int j=; j<=m; j++)
add(s, n+j, have[j][i], );
for(int j=; j<=m; j++)
for(int l=; l<=n; l++)
add(n+j, l, INF, ca[i][l][j]); ret += max_flow();
}
cout<< ret <<endl;
} return ;
}

最新文章

  1. HTML和XHTML的区别
  2. 如何更方便地调试javascript代码
  3. SQL中 Left Join 与 Right Join 与 Inner Join 与 Full Join的区别
  4. gcc常用选项
  5. github上如何合并别人的pull request
  6. 搜索服务器xunsearch实现
  7. Linux下面如何运行.sh文件
  8. AS3事件机制概述
  9. java序列化是什么和反序列化和hadoop序列化
  10. 快速找到Office应用程序安装路径
  11. 关于基因组注释文件GTF的解释
  12. CSS盒模型(Box Model)
  13. 打包发布Python模块或程序,安装包
  14. process 多进程写法 multiprocessing
  15. laravel控制器方法中,用函数作为变量进行传递时的处理方法
  16. HTML图片热区map area的用法(转)
  17. STM32F4 Timer External Clock TI2 Both Edges Demo
  18. Ubuntu 16.04系统下apt-get和dpkg区别
  19. Spring学习(5):DI的配置
  20. 20155307 2016-2017-2 《Java程序设计》第6周学习总结

热门文章

  1. 驱动笔记 - platform中断程序
  2. 并行编程(Parallel Framework)
  3. SpringBoot日记——分布式篇
  4. 计算机网络什么是OSI7层模型、TCP/IP4层模型理解
  5. MariaDB 安装与启动 过程记录
  6. Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)-C. Plasticine zebra
  7. JDK+JAVA+maven+IDEA
  8. 《Linux内核分析》读书笔记(四章)
  9. Proxy 示例
  10. boost::asio之(一)简单客户端服务器回显功能