题意】:

有N个人,M个仓库,每个人需要物品,个数都等于共同的K,仓库中有对应的K件物品的数量,随后给K个N*M矩阵(小写k, n, m表示K,N,M对应的子集),表明m个仓库到第n个人的位置运送k物品的花费,求

满足所有人的订单要求所需要的花费,如果不能满足所有人则输出-1

思路】:

我的思路是建立源点sp,汇点tp, 把仓库和人所在的点都进行拆分,对每个仓库拆分成K个点,可以想象成一个大仓库由K个小仓库组成,每个小仓库只发放第k种物品,每个人也分成K个点,每个点接受一种k物品,sp与仓库的拆点进行连边,权重为这个小仓库存放的k物品的数量,花费为0,人的拆点与tp连边,权重为人拆点所需要的k物品的数量,费用为0,最后将仓库的拆点人的拆点进行连边,权重为inf,费用为矩阵中对应的费用。

重要】——>解决TLE问题

我的想法可能与网上的题解不同,我看有很多是分别跑k次费用流,最后的费用总和为结果,我在一开始也是疯狂TLE,然后加上特判就过了?

特判】——>解决TLE

将输入分成三部分与N有关——与M有关——K个N*M矩阵

判定是否有供不应求的情况,将前两部分输入(N*K和N*K)分别存储下来,N*K代表所需要的部分,M*K代表供应的部分,对每个k进行遍历,然后求每个n的和sum1,每个m的和sum2,如果sum1>sum2则不对第三部分输入处理(K个N*M矩阵),待输入结束后不进行费用流算法,直接输出-1即可

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std; const int maxn = 1e4 + ;
const int maxe = 1e6 + ;
const int N = + ;
const int inf = 0x3f3f3f3f;
struct edge{
int to, w, c, next;
} ed[maxe];
int head[maxn], tot, ns;
int n, m, k, ware[N][N], p[N][N];
int sp, tp, d[maxn], pre[maxn], a[maxn];
bool inq[maxn];
inline void init(){
memset( head, -, sizeof(head) ) ;
tot = ;
ns = (n+m)*k+;
sp = ; tp = ns-;
} inline void add( int u, int v, int w, int c ){
ed[++tot].to = v; ed[tot].w = w; ed[tot].c = c; ed[tot].next = head[u]; head[u] = tot;
ed[++tot].to = u; ed[tot].w = ; ed[tot].c = -c; ed[tot].next = head[v]; head[v] = tot;
} inline bool spfa( int &flow, int &cost ){
for( int i=; i<ns; i++ ){
inq[i] = ;
d[i] = inf;
}
queue<int> q;
d[sp] = pre[sp] = ;
a[sp] = inf;
inq[sp] = ;
q.push(sp);
while( q.size() ){
int x = q.front();
q.pop();
inq[x] = ;
for( int i=head[x]; ~i; i=ed[i].next ){
int y = ed[i].to;
if( ed[i].w> && d[y]>d[x]+ed[i].c ){
d[y] = d[x]+ed[i].c;
pre[y] = i;
a[y] = min(a[x], ed[i].w);
if( !inq[y] ){
inq[y] = ;
q.push(y);
}
}
}
}
if( d[tp]==inf ) return ;
flow += a[tp];
cost += a[tp]*d[tp];
for( int x=tp; x!=sp; x=ed[pre[x]^].to ){
ed[pre[x]].w -= a[tp];
ed[pre[x]^].w += a[tp];
}
return ;
} inline void mcmf( int &flow, int &cost ){ while(spfa(flow, cost)); } int main(){
while( ~scanf("%d%d%d", &n, &m, &k), (n||m||k) ){
init();
int num, sum = ;
for( int i=; i<=n; i++ )
for( int j=; j<=k; j++ ){
scanf("%d", &p[i][j]);
sum += p[i][j];
add( (i-)*k+j, tp, p[i][j], );
}
for( int i=; i<=m; i++ )
for( int j=; j<=k; j++ ){
scanf("%d", &ware[i][j]);
add( sp, (i-)*k+j+n*k, ware[i][j], );
}
bool flag = ;
for( int i=; i<=k; i++ ){
int sum1 = , sum2 = ;
for( int j=; j<=n; j++ ) sum1 += p[j][i];
for( int j=; j<=m; j++ ) sum2 += ware[j][i];
if( sum2<sum1 ) {flag = ; break;} //判断是否存在供不应求,如果存在则直接输出-1
}
for( int l=; l<=k; l++ )
for( int i=; i<=n; i++ )
for( int j=; j<=m; j++ ){
int num;
scanf("%d", &num);
if( flag ) continue; //如果出现供不应求则不进行处理,只读取数据即可
add( (j-)*k+l+n*k, (i-)*k+l, inf, num );
}
if( flag ){ puts("-1"); continue; } //输出-1
int flow = , cost = ;
mcmf(flow, cost);
if( flow>=sum ) printf("%d\n", cost);
else puts("-1");
} return ;
}

POJ 2516Minimum Cost(最小费用流+特判)的更多相关文章

  1. poj 2516Minimum Cost

    http://poj.org/problem?id=2516 #include<cstdio> #include<cstring> #include<algorithm& ...

  2. poj 2049(二分+spfa判负环)

    poj 2049(二分+spfa判负环) 给你一堆字符串,若字符串x的后两个字符和y的前两个字符相连,那么x可向y连边.问字符串环的平均最小值是多少.1 ≤ n ≤ 100000,有多组数据. 首先根 ...

  3. POJ 2516 Minimum Cost 最小费用流

    题目: 给出n*kk的矩阵,格子a[i][k]表示第i个客户需要第k种货物a[i][k]单位. 给出m*kk的矩阵,格子b[j][k]表示第j个供应商可以提供第k种货物b[j][k]单位. 再给出k个 ...

  4. POJ 2516 Minimum Cost 最小费用流 难度:1

    Minimum Cost Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 13511   Accepted: 4628 Des ...

  5. Poj(2195),最小费用流,SPFA

    题目链接:http://poj.org/problem?id=2195 Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  6. Poj(3259),SPFA,判负环

    题目链接:http://poj.org/problem?id=3259 Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submis ...

  7. poj 2942(点双连通+判奇圈)

    题目链接:http://poj.org/problem?id=2942 思路:我们对于那些相互不憎恨的骑士连边,将每次参加会议的所有人(不一定是整个骑士团,只需人数>=3且为奇数)看做一个点双联 ...

  8. Farm Tour POJ - 2135 (最小费用流)

    When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 <= ...

  9. Poj 3259 Wormholes(spfa判负环)

    Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 42366 Accepted: 15560 传送门 Descr ...

随机推荐

  1. TCP三次握手及四次断开,TCP有限状态机

    TCP 的连接建立 上图画出了 TCP 建立连接的过程.假定主机 A 是 TCP 客户端,B是服务端.最初两端的 TCP 进程都处于 CLOSED 状态.图中在主机下面的是 TCP进程所处的状态.A ...

  2. MacBook安装WIN7开机黑屏的解决办法

    同事的一台Macbook,全盘用diskgenius格式化为MBR分区,支持BIOS启动,安装ghost版本的WIN7,开机黑屏,看了网上的帖子没有用,插入启动盘按option键选择从优盘启动,用di ...

  3. [LeetCode] 146. LRU Cache 最近最少使用页面置换缓存器

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  4. TJOI 2015 概率论(生成函数)

    题意 ​ 求一棵随机生成的有根二叉树(节点无标号,各种不同构的情况随机出现)叶子结点个数的期望. 思路 ​ 用生成函数做是个好题. ​ 我们考虑设 \(n\) 个节点,所有不同构二叉树叶子结点的总和为 ...

  5. vs2019 更新之后无法用ctrl+d再设置回来..

    工具-选项-环境-键盘

  6. torch_03_二分类

    logistic回归 博客链接:https://www.cnblogs.com/home123/p/7356523.html 分类器:监督学习从数据中学习一个分类模型或者分类决策函数,被称为分类器(c ...

  7. linux centos安装教程

    linux centos安装教程1 CentOS-7-x86_64-DVD-1511.iso 这个是dvd版本 2 CentOS-7-x86_64-Minimal-1511.iso 这个迷你版 是没有 ...

  8. html5 video获取实时播放进度的方法

    getvideoprogress(); function getvideoprogress() { setTimeout(function () { var vid = document.getEle ...

  9. [转帖]CHROME开发者工具的小技巧

    CHROME开发者工具的小技巧 https://coolshell.cn/articles/17634.html 需要仔细学习看一看呢. 2017年01月19日 陈皓 评论 58 条评论  64,08 ...

  10. 一个简单的 ValueTask 的示例

    Task 确实有潜在的缺点,特别是对于实例创建很多  并且高吞吐量和性能是关键问题的场景  :  Task 是一个类.作为一个类,这意味着任何需要创建一个对象的操作都需要分配一个对象,分配的对象越多, ...