题意:

n个糖果,m个孩子,给一个矩阵like[i][j]表示第i个孩子喜欢第j个糖果。 如果孩子拿到他喜欢的糖果,那么他将会增加k个快乐度,拿到不喜欢的,增加1。 如果孩子i的欢乐值大于B[i],那么他就是开心的。

问,能否有一种分配方案,让所有孩子都开心,有输出yes,没有no。

思路:(讲的不好请见谅,大牛勿喷)

起初是看了一个大牛的一篇关于网络流建模的总结,里面有个跟这个题同名的题,只是它里面k是固定的就是2.里面的做法是用单纯的最大流做的,没有考虑到费用。建图是这样的,每颗糖作为一个点连边(s,i,1),每个小孩j座位一个点连边(j,t,b[i]/2),若小孩j喜欢糖果i则连边(i,j,1),然后最大流一下,得ans,,ans+n>=求和(b[i]).他的考虑是反正每颗糖最后都是要分给孩子的,那么它一定会为总权值贡献1,所以这个1就不考虑了,最后加上n,只考虑如果孩子喜欢这个糖而带来的额外的贡献,上述题里面这样做是没问题的。其实这两道题的思路很像,hdu4322应该是改变自上述题的,将k变成了变化的,而不是2了。

一开始我拿到这个题的时候,就直接套了上述题的思路,想将小孩j作为一个点练边(j,t,b[i]/k),表示该孩子能用b[i]/k块糖果填补一下快乐度,走一边最大流,然后用剩下的n-ans块糖来填补这些孩子不够的快乐度。后来一想这样做是不对的,比如k=3,b[i]%k==2,如果套上述建图方法,也就是说我需要用两块糖来填补这个孩子的快乐度,并且这两块糖里面可能会有他喜欢的糖果,因为走最大流的时候只让它满足了b[i]/k个流量。但这时你给这个孩子一个他喜欢的糖果,快乐度会超出1,但是糖果使用上是更少了,这是更合理的。所以只用最大流是错的。这时候就想到了需要用到费用流。

其中的总费用代表了给这些孩子喜欢的糖果所能得到的总贡献,每给一个孩子一块它喜欢的糖果,其费用是k,而且每个孩子的快乐度到达b[i]即可,就算超过了也按b[i]算,因为超过的部分没有意义。然后呢,详细考虑一下,如果一个孩子b[i]%k==0 那么建边(j,t,b[i]\k,k),容量是b[i]\k,费用是k,那么如果b[i]%k!=0呢?

如果==1,也就是说剩余的快乐度就算你给他喜欢的糖果效果也跟普通糖果一样,这时候就不需要建边了。如果>1,这时候就需要再建第二条边(j,t,1,b[i]%k),容量是1,费用是b[i]%k,它的意义就是用一个喜欢的糖果把b[i]%k的部分填补掉。但这时候再考虑一个问题,就是如果你套最小费用最大流的板子,它肯定会先走第二条边,但这样是不对的。这样的话就有可能导致费用是k的边的容量有剩余时,而第二条边已经被流了,道理自己想吧。所以我们需要做的就是先让它流费用大的,所以这是个最大费用最大流。只需要把费用取相反数,流完再取反就好了。

最后判断n-ans>=all(b[i])-cost是否成立就好了,也就是剩余的没人喜欢(或者被某些孩子喜欢但这个孩子快乐度够了而不能要)的糖果是不是能满足剩余的快乐度。

代码:最小费用流的板子屯一发

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
const int inf=1<<29;
const int maxn=1000;struct node
{int v,next,cap,w;
};
node edge[maxn<<1];
int head[maxn];
int cnt;
int dis[maxn],pe[maxn],pv[maxn];
int m,n,k;
int cost,flow;
int S,T,all;
bool mark[maxn];void init()
{memset(head,-1,sizeof(head));cnt=0;all=0;
}void add(int a,int b,int c,int d)
{edge[cnt].v=b;edge[cnt].cap=c;edge[cnt].w=d;edge[cnt].next=head[a];head[a]=cnt++;edge[cnt].v=a;edge[cnt].cap=0;edge[cnt].w=-d;edge[cnt].next=head[b];head[b]=cnt++;
}int mindinic()
{int Min;cost=0,flow=0;while(1){for(int i=0;i<=T;i++) dis[i]=inf;memset(mark,false,sizeof(mark));queue<int> q;dis[0] = 0;q.push(0);mark[0]=true;int cur;while(!q.empty()){cur = q.front();q.pop();mark[cur]=false;for(int i = head[cur]; i != -1; i = edge[i].next){node x=edge[i];if(x.cap&& dis[x.v]>x.w+dis[cur] ){dis[x.v] = dis[cur] + x.w;pe[x.v]=i;pv[x.v]=cur;if(!mark[x.v]){mark[x.v]=true;q.push(x.v);}}}}if(dis[T]==inf) return cost;Min=inf;for(int j=T; j!=S; j=pv[j])Min=min(Min,edge[pe[j]].cap);flow+=Min;cost+=dis[T]*Min;for(int j=T; j!=S; j=pv[j])edge[pe[j]].cap-=Min,edge[pe[j]^1].cap+=Min;}
}int main()
{int cas=1;int t,x;scanf("%d",&t);while(t--){scanf("%d%d%d",&n,&m,&k);init();S=0,T=n+m+1;for(int i=1; i<=n; i++){add(S,i,1,0);}for(int i=1; i<=m; i++){scanf("%d",&x);all+=x;add(n+i,T,x/k,-k);if(x%k>1){add(n+i,T,1,-x%k);}}for(int i=1; i<=m; i++){for(int j=1; j<=n; j++){scanf("%d",&x);if(x){add(j,n+i,1,0);}}}int tmp=-mindinic();//用上的喜欢的糖果能够填充的快乐度if(n-flow>=all-tmp)//剩余的没人喜欢的糖果是否能填充剩余的快乐度printf("Case #%d: YES\n",cas++);elseprintf("Case #%d: NO\n",cas++);}return 0;
}

hdu4322 candy 费用流相关推荐

  1. BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]

    3130: [Sdoi2013]费用流 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special Judge Submit: 960  Solved:  ...

  2. [BZOJ 1221][HNOI2001]软件开发(费用流)

    Description 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员 ...

  3. 费用流 -- 四川省赛F-Direction Setting [拆边成点+费用流]

    题目链接 题目大意: 就是给你一个nnn个点mmm条边的无向图,每个点有个值是aia_iai​现在你把每条边都赋予一个方向之后这个图就是有向图了,那么设第iii个点的入度是did_idi​,现在设 D ...

  4. UVA1411 Ants(带权二分图的最大完美匹配、zkw费用流)

    题解 给定一些黑点白点,要求一个黑点链接一个白点并且线段不相交(转成二分图最大权匹配使用费用流解决)<训练指南>P351 输出方案:满流即为答案(满流是指这条路的流量跑满了,也就是说edg ...

  5. 餐巾计划问题 线性规划与网络流24题之10 费用流

    相关知识:最小费用(最大)流 问题描述: 一个餐厅在相继的N 天里, 每天需用的餐巾数不尽相同. 假设第i天需要ri块餐巾(i=1, 2,-,N).餐厅可以购买新的餐巾,每块餐巾的费用为p分:或者把旧 ...

  6. BZOJ1150[CTSC2007]数据备份Backup——模拟费用流+堆+链表

    题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游 ...

  7. bzoj3171: [Tjoi2013]循环格(费用流)

    传送门 其实这题的建图并不难(虽然我并没有想出来) 首先,每一个点的入度和出度必须为$1$ 那么我们考虑拆点 每个点的出度点向它能到达的点的入度点连边,容量$1$,如果方向为原来的方向则费用$0$否则 ...

  8. 洛谷 - P2045 - 方格取数加强版 - 费用流

    原来这种题的解法是费用流. 从一个方格的左上走到右下,最多走k次,每个数最多拿走一次. 每次走动的流量设为1,起始点拆点成限制流量k. 每个点拆成两条路,一条路限制流量1,费用为价值相反数.另一条路无 ...

  9. 【BZOJ2245】[SDOI2011]工作安排 拆边费用流

    [BZOJ2245][SDOI2011]工作安排 Description 你的公司接到了一批订单.订单要求你的公司提供n类产品,产品被编号为1~n,其中第i类产品共需要Ci件.公司共有m名员工,员工被 ...

最新文章

  1. 【蓝桥java】进制与整除之尼姆堆
  2. 连这几个源码都没啃透,那面试高级开发的事等等再来!
  3. 【 MATLAB 】使用案例研究 DTFT 的对称性
  4. 手机实名制的一个应用,电信行业的一个可改进之处
  5. 基于继承类的属性模版中无法绑定的原因和解决方法
  6. python统计自己微信好友并抓取信息
  7. 【渝粤教育】 国家开放大学2020年春季 2542行政组织学 参考试题
  8. Python的time模块和datatime模块
  9. identity_insert 如何改为on_十分钟教你如何快速提高Laya构建速度,还不快来康康?...
  10. abap判断包含字符当中包含小数点_剑指Offer整理3 -- 栈和队列 + 数学和字符串
  11. linux 设置ssh免密登录
  12. Java Web整合开发(37) -- SVN
  13. 快递单中抽取关键信息【一】----基于BiGRU+CR+预训练的词向量优化
  14. 20位顶级设计师的桌面环境
  15. JPA并发save失效
  16. Android Socket 编程(WIFI 和 ADB)
  17. linux u盘 中毒,linux对中毒u盘分区和格式化
  18. python语言中param_四、python之函数详解一
  19. Scala 中的 Array 数组 详解
  20. 数据结构与算法:树(Tree)

热门文章

  1. python 累加直方图_二维数组的Python累积直方图
  2. Chrome插件(扩展)开发全攻略(干货)
  3. 文件服务器 协同编辑,在 Office 365 中协同共享一同编辑文件
  4. Centos7操作系统搭建Snipe-IT资产管理系统
  5. Mate50落后又贵,iPhone性能超强更便宜,消费者还期待华为?
  6. Matplotlib基础02:散点图、折线图与柱状图
  7. C++(常函数、常对象)
  8. Charles 2 - breakpoint断点、compose编辑、rewrite重写、map映射重定向、repeat重发、throttling弱网测试
  9. python如何定义函数k_Python 函数
  10. 微信小程序的开发方式有哪些