Minimum Cost POJ - 2516(模板题。。没啥好说的。。)
2024-09-27 08:50:54
题意:
从发货地到商家 送货 求送货花费的最小费用。。。
有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 ;
}
最新文章
- HTML和XHTML的区别
- 如何更方便地调试javascript代码
- SQL中 Left Join 与 Right Join 与 Inner Join 与 Full Join的区别
- gcc常用选项
- github上如何合并别人的pull request
- 搜索服务器xunsearch实现
- Linux下面如何运行.sh文件
- AS3事件机制概述
- java序列化是什么和反序列化和hadoop序列化
- 快速找到Office应用程序安装路径
- 关于基因组注释文件GTF的解释
- CSS盒模型(Box Model)
- 打包发布Python模块或程序,安装包
- process 多进程写法 multiprocessing
- laravel控制器方法中,用函数作为变量进行传递时的处理方法
- HTML图片热区map area的用法(转)
- STM32F4 Timer External Clock TI2 Both Edges Demo
- Ubuntu 16.04系统下apt-get和dpkg区别
- Spring学习(5):DI的配置
- 20155307 2016-2017-2 《Java程序设计》第6周学习总结
热门文章
- 驱动笔记 - platform中断程序
- 并行编程(Parallel Framework)
- SpringBoot日记——分布式篇
- 计算机网络什么是OSI7层模型、TCP/IP4层模型理解
- MariaDB 安装与启动 过程记录
- Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)-C. Plasticine zebra
- JDK+JAVA+maven+IDEA
- 《Linux内核分析》读书笔记(四章)
- Proxy 示例
- boost::asio之(一)简单客户端服务器回显功能