poj 2516
来源:互联网 发布:外国知乎瞧不起中国 编辑:程序博客网 时间:2024/05/21 09:49
题目概述
市场上有K种货物流通,编号1到K,有N家店,编号1到N,每家都需要一定量的各种货,M家供货商,编号1到M,每家库存有一定量的各种货,从供货商运货到店面会产生运费,问供货商库存能否满足商店的货物需求,若能满足,求最小运输费用
时限
4000ms/12000ms
输入
第一行整数N,M,K,其后N行,每行K个整数,为该商店需要的各种货数量,货按编号升序给出,商店按编号升序给出,其后M行,每行K个整数,为该供货商库存各种货数量,按升序给出,其后K个N行M列的矩阵,行号代表商店,列号代表供货商,值为供货商运送一单位该种货物到商店的运费,按货号升序给出矩阵,输入到N=M=K=0结束
限制
0< N,M,K<50
输出
每行一个数,若无法满足需求,为-1,否则为最小运费
样例输入
1 3 3
1 1 1
0 1 1
1 2 2
1 0 1
1 2 3
1 1 1
2 1 11 1 1
3
2
200 0 0
样例输出
4
-1
讨论
图论,网络流,费用流,最小增广路算法,这个题说的非常直白,一看就知道是费用流,构图上也几乎没有难度,源点,供货商,商店,汇点,每种货物单独考虑,单独构图,源点到供货商残量为库存量,费用0,供货商到商店残量无穷大,费用就是单位货物的运费,这点需要稍微留心,其反向边残量0,费用为运费的相反数,不是0,像额这种刚入门的很难发现这条错误,商店到汇点残量为需求量,费用0,其他货物类别同理构图,当供不应求时,这张图的最大流会小于所有商店对该货物需求的和,由此进行判断
实现层面上,没有什么难度,只是由于输入比较奇怪,读入的时候需要稍微细心一点
虽说开个三维数组相当浪费,但是着实是非常方便,加上算法也不是什么高级货色,暂且如此
题解状态
5112K,391MS,C++,1878B
题解代码
#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;#define INF 0x3f3f3f3f#define MAXN 54#define memset0(a) memset(a,0,sizeof(a))int N, M, K, S, T;//商店数 供货商数 货类别数 源点 汇点int R[MAXN][MAXN * 2][MAXN * 2], W[MAXN][MAXN * 2][MAXN * 2], dis[MAXN * 2], from[MAXN * 2], require[MAXN];//残量矩阵 费用矩阵 最短路长度 父节点 每种货物的总需求量queue<int>q;bool inq[MAXN * 2];int bellman_ford(int K, int N)//第一个参数是货的编号 第二个是图上节点总数{ int least = 0, most = 0;//最小费用 最大流 while (1) {//下面就是bellman_ford算法 稍微改一下就可以 int flow = INF; for (int p = 0; p < N; p++) dis[p] = INF; dis[S] = 0; q.push(S); while (!q.empty()) { int a = q.front(); q.pop(); inq[a] = 0; for (int p = 0; p < N; p++) if (R[K][a][p] && dis[p] > dis[a] + W[K][a][p]) {//得有残量才能松弛 dis[p] = dis[a] + W[K][a][p]; from[p] = a; flow = min(flow, R[K][a][p]); if (!inq[p]) { q.push(p); inq[p] = 1; } } } if (dis[T] == INF) {//当没有增广路时 if (most < require[K])//供不应求 return -1; return least; } most += flow; least += flow*dis[T]; for (int p = T; p; p = from[p]) { int i = from[p]; R[K][i][p] -= flow; R[K][p][i] += flow;//顺原路返回进行增广 } }}int fun(){ T = M + N + 1;//构造的汇点 源点是0 for (int p = 1; p <= N; p++) for (int i = 0; i < K; i++) { scanf("%d", &R[i][M + p][T]);//input//商店到汇点 require[i] += R[i][M + p][T]; } for (int p = 1; p <= M; p++) for (int i = 0; i < K; i++) scanf("%d", &R[i][S][p]);//input//读入源点到供货商 for (int p = 0; p < K; p++) for (int i = 1; i <= N; i++) for (int u = 1; u <= M; u++) { scanf("%d", &W[p][u][M + i]);//input//读入供货商到商店 W[p][M + i][u] = -W[p][u][M + i];//构造反向边 R[p][u][M + i] = INF; } int cost = 0; for (int p = 0; p < K; p++) { int add = bellman_ford(p, M + N + 2); if (add == -1) return -1; cost += add; } return cost;}int main(void){ //freopen("vs_cin.txt", "r", stdin); //freopen("vs_cout.txt", "w", stdout); while (~scanf("%d%d%d", &N, &M, &K) && (N || M || K)) {//input printf("%d\n", fun());//output memset0(R); memset0(W); memset0(require); }}
EOF
- poj 2516
- poj 2516
- poj 2516
- POJ 2516
- poj 2516
- poj 2516
- POJ 2516 Minimum Cost
- poj 2516 Mininum Cost
- Poj 2516 Minimum Cost
- POJ 2516 Minimum Cost
- POJ-2516-Minimum Cost
- poj 2516 Minimum Cost
- POJ 2516 Minimum Cost
- POJ 2516 Minimum Cost
- POJ 2516 Minimum Cost
- POJ 2516 Minimum Cost
- poj 2516 Minimum Cost
- POJ-2516-Minimum Cost
- 11g r2 删除节点操作
- pyqt4文档阅读(3):QLCDNumber
- 业余草站长告诉你:网站被克隆了怎么办?
- C++面试题
- HttpMessageConverter
- poj 2516
- 在{互联网}的大海中如何避免【SEO黑帽】
- gdb查找段错误
- SpringMVC注解@initbinder解决类型转换问题
- 【NOIP2015】信息传递
- Leetcode 202. Happy Number
- 初次使用python之在notepad++中直接运行python代码
- 浅拷贝与深拷贝的区别
- Windows下scala环境搭建