题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4322

思路:建图真的是太巧妙了!直接copy大牛的了:

由于只要得到糖就肯定有1个快乐度,在这一点上糖的效果是等效的。所以只要考虑有特殊效果的糖的分配就可以了。

当快乐的程度超过b[i]时,多出来的部分就浪费了,为了使浪费尽可能少,我们用费用流加以控制,当获得最大费用最大流的时候,这是的费用的利用率就是最高的。在建图时只需考虑特殊的糖就可以了,建图方法:

原点到每个糖:流为1,费用为0。如果糖对某个人有特殊效果,连边:流为1,费用为0。人向汇点连边:最终快乐的程度不超过b[i]的情况:流为b[i]/k,限制这样的糖的数量,费用为k,因为特殊效果全部利用上了。快乐程度超过b[i]的情况:流为1,限制流量不超过b[i],费用为b[i] % k,因为多出来的快乐无效。当b[i] % k == 0时,这样的边没有必要。当b[i] % k == 1时,这时的糖和普通的糖无异,没必要连边。

最终算出来的费用就是特殊的糖被充分利用后已经分配的快乐程度,最大流为为了达到这样的程度使用的糖的数量,这样就还剩N - 最大流数量的糖被我们当做普通的糖使用,只要剩下的普通的糖的数目大于还需填充的快乐程度,就可以满足条件。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<queue>
  6. using namespace std;
  7. #define MAXN 55
  8. #define MAXM 4444
  9. #define inf 1<<30
  10.  
  11. struct Edge{
  12. int v,cap,cost,next;
  13. }edge[MAXM];
  14.  
  15. int vs,vt,n,m,NE,sum,k;
  16. int head[MAXN];
  17.  
  18. void Insert(int u,int v,int cap,int cost)
  19. {
  20. edge[NE].v=v;
  21. edge[NE].cap=cap;
  22. edge[NE].cost=cost;
  23. edge[NE].next=head[u];
  24. head[u]=NE++;
  25.  
  26. edge[NE].v=u;
  27. edge[NE].cap=;
  28. edge[NE].cost=-cost;
  29. edge[NE].next=head[v];
  30. head[v]=NE++;
  31. }
  32.  
  33. int dist[MAXN],pre[MAXN],cur[MAXN];
  34. bool mark[MAXN];
  35. bool spfa(int vs,int vt)
  36. {
  37. memset(mark,false,sizeof(mark));
  38. fill(dist,dist+MAXN-,-inf);
  39. dist[vs]=;
  40. queue<int>que;
  41. que.push(vs);
  42. while(!que.empty()){
  43. int u=que.front();
  44. que.pop();
  45. mark[u]=false;
  46. for(int i=head[u];i!=-;i=edge[i].next){
  47. int v=edge[i].v,cost=edge[i].cost;
  48. if(edge[i].cap>&&dist[u]+cost>dist[v]){
  49. dist[v]=dist[u]+cost;
  50. pre[v]=u;
  51. cur[v]=i;
  52. if(!mark[v]){
  53. mark[v]=true;
  54. que.push(v);
  55. }
  56. }
  57. }
  58. }
  59. return dist[vt]!=-inf;
  60. }
  61.  
  62. int MinCostFlow(int vs,int vt)
  63. {
  64. int flow=,cost=;
  65. while(spfa(vs,vt)){
  66. int aug=inf;
  67. for(int u=vt;u!=vs;u=pre[u]){
  68. aug=min(aug,edge[cur[u]].cap);
  69. }
  70. flow+=aug,cost+=dist[vt]*aug;
  71. for(int u=vt;u!=vs;u=pre[u]){
  72. edge[cur[u]].cap-=aug;
  73. edge[cur[u]^].cap+=aug;
  74. }
  75. }
  76. return n-flow>=sum-cost;
  77. }
  78.  
  79. int like[MAXN][MAXN];
  80. int B[MAXN];
  81. int main()
  82. {
  83. // freopen("1.txt","r",stdin);
  84. int _case,t=;
  85. scanf("%d",&_case);
  86. while(_case--){
  87. scanf("%d%d%d",&n,&m,&k);
  88. NE=,vs=,vt=n+m+,sum=;
  89. memset(head,-,sizeof(head));
  90. for(int i=;i<=m;i++){
  91. scanf("%d",&B[i]);
  92. sum+=B[i];
  93. }
  94. for(int i=;i<=n;i++)Insert(vs,i,,);
  95. for(int i=;i<=m;i++){
  96. for(int j=;j<=n;j++){
  97. scanf("%d",&like[i][j]);
  98. if(like[i][j]==)Insert(j,i+n,,);
  99. }
  100. Insert(i+n,vt,B[i]/k,k);
  101. if(B[i]%k>){
  102. Insert(i+n,vt,,B[i]%k);
  103. }
  104. }
  105. printf("Case #%d: ",t++);
  106. if(MinCostFlow(vs,vt)){
  107. puts("YES");
  108. }else
  109. puts("NO");
  110. }
  111. return ;
  112. }

hdu 4322(最大费用最大流)的更多相关文章

  1. 【网络流#2】hdu 1533 - 最小费用最大流模板题

    最小费用最大流,即MCMF(Minimum Cost Maximum Flow)问题 嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(Ho ...

  2. hdu 1533(最小费用最大流)

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  3. hdu 4862KM&最小费用最大流

    /*最小K路径覆盖的模型,用费用流或者KM算法解决, 构造二部图,X部有N*M个节点,源点向X部每个节点连一条边, 流量1,费用0,Y部有N*M个节点,每个节点向汇点连一条边,流量1, 费用0,如果X ...

  4. HDU 4322Candy 最大费用最大流

    由于被小孩子不喜欢的糖果的对小孩产生的效力是一样的,所以我们在网络流的时候先不考虑. 1 - 源点0到1~N个糖果,容量为1,费用为02 - 根据like数组,like[i][j] == 1时在糖果j ...

  5. hdu 4322 最大费用流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4322 #include <cstdio> #include <cstring> ...

  6. hdu 4067(最小费用最大流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4067 思路:很神奇的建图,参考大牛的: 如果人为添加t->s的边,那么图中所有顶点要满足的条件都 ...

  7. HDU 1533 最小费用最大流(模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=1533 这道题直接用了模板 题意:要构建一个二分图,家对应人,连线的权值就是最短距离,求最小费用 要注意void ...

  8. HDU 4406 最大费用最大流

    题意:现有m门课程需要复习,已知每门课程的基础分和学分,共有n天可以复习,每天分为k个时间段,每个时间段可以复习一门课程,并使这门课程的分数加一,问在不挂科的情况下最高的绩点. 思路:(没做过费用流的 ...

  9. hdu 3667(最小费用最大流+拆边)

    Transportation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

随机推荐

  1. vue 仿ele 开发流程

    技术栈: vue2 vuex vue-router axios webpack eslint better-scroll 1.安装插件 npm install vue-resource babel-r ...

  2. jQuery-mobile 学习笔记之三(事件监听)

    续上 触摸事件 - 当用户触摸屏幕时触发(敲击和滑动) 滚动事件 - 当上下滚动时触发 方向事件 - 当设备垂直或水平旋转时触发 页面事件 - 当页面被显示.隐藏.创建.载入以及/或卸载时触发 一.初 ...

  3. [Objective-C] - NSObject

    Foundation Framework Classes Data Storage:    NSData provides object-oriented storage for arrays of ...

  4. 《Java并发编程的艺术》读书笔记:等待/通知机制

    看这本书之前,对wait和notify认识大概就是,调用wait的线程A堵塞之后,一旦另外有线程调用notify方法.线程A会立马从wait方法处返回.看完这本书后.发现自己的认识实在太肤浅了.... ...

  5. 网页会计系统 FrontAccounting

    FrontAccounting (FA)是一个针对企业ERP供应链的网页会计系统.FA 允許多使用者.多語系和多國貨幣. FA允许多使用者.多语系和多国货币.FA接续OpenAccounting (O ...

  6. 【转】OMCS网络语音视频聊天框架(跨平台)

    原文地址:http://www.cnblogs.com/zhuweisky/archive/2012/08/02/2617877.html OMCS网络语音视频框架是集成了语音通话.视频通话.远程桌面 ...

  7. unity3d动态操作组件

    利用范型,动态操作组件(添加或删除) e.AddComponent<CubeTranslate> ();//动态添加组件 Destroy (e.GetComponent<CubeTr ...

  8. MongoDB Query 判断为空 取值为空的时间

    if (!string.IsNullOrEmpty(STATES)) { DateTime? dtnull = null; //Return if (STATES == "Return&qu ...

  9. 自制MVC之工具类插件一

    1).BreakRomoteURLAttribute 提交或交互的URL数据是否来源于其它地方,站内提交,防止跨站 2). DataAttribute 取得post或get提交的数据.如果没有特殊设置 ...

  10. atitit.验证码识别step3----去除边框---- 图像处理类库 attilax总结java版本

    atitit.验证码识别step3----去除边框---- 图像处理类库 attilax总结java版本 1. 去除边框思路原理 1 2. Thumbnailator 是一个用来生成图像缩略图.裁切. ...