title: woj1008feedinganimals2-贪心-网络流

date: 2020-03-07

categories: acm

tags: [acm,woj,网络流,贪心]

中等题。

标准的网络流。

注意贪心只是能ac但是有反例。

description

To show your intelligence to the Lord,you must solve the problem as follows:

Suppose there are m persons and n animals. A person can feed an animal peacefully if he/she is liked by the animal.

Given a list of which person is liked by which animal,you are to determine whether all animals can be feeded peacefully on

condition that every person can feed at most k animals.

输入格式

There will be multiple test cases. For each test case,the first line contains two integers m(1 <= m <= 100) and

n(1 <= n <= 100), where m indicates the number of persons and n indicated the number of animals.The following lines

contain the m * n 0-1 matrix indicating which person is liked by which animal.The ith person is liked by the jth animal

if the jth element of the ith line is 1. The last line for each test case contains a single integer k,indicating the

maximal number of animals one person can feed.

输出格式

For each test case,output "Yes" if all animals can be feeded peacefully,"No" otherwise.

样例输入

2 8

1 1 0 1 0 0 1 1

1 1 1 0 1 1 1 1

2

7 2

1 1

1 1

1 1

1 1

1 1

1 1

1 1

2

样例输出

No

Yes

code

  1. //1.1
  2. // m,n 1-100,直接开就完事了
  3. // 一开始想做DFS,每次选一列中的一个,然后往下,复杂度爆了
  4. //换贪心和网络流
  5. //贪心法。每个人权重=1.0*love[i][j]/maxn,也就是能喂的动物越少,权重越大,越优先安排他喂
  6. //贪心有反例
  7. //是网络流题
  8. #include <iostream>
  9. #include<vector>
  10. #include<cstdio>
  11. #include<stack>
  12. using namespace std;
  13. int person,animals,maxn;
  14. int love[105][105];
  15. int cnt[105]; //根据上限每个人还能喂几个 如果每个人的上限数量不同,表示每个人的数量然后计算权重就行
  16. int summ[105]; //每个人本来能喂养的综合
  17. bool used[105][105];
  18. double capacity[105][105]; //每个动物占某人可喂养的权重
  19. //复杂度 100^100 。因为这个剪枝不了,就是说如果上一层采取不同的人喂养,可能这一层原来不行的又行了
  20. bool dfs(int tmp){ //把每一列看成树的一层,dfs
  21. if(tmp==animals) //到了animals+1层,说明都分配好了
  22. return true;
  23. for (int i = 0; i <= person; i++) //
  24. if (used[i][tmp] == false&&love[i][tmp]==1&&cnt[i]>0) { //这个人可喂并且没用过
  25. used[i][tmp]=true;cnt[i]--;
  26. if(dfs(tmp + 1)) //这样可行的话,true就行,因为是有一种可行情况就行
  27. return true;
  28. cnt[i]++; used[i][tmp]=false; //我傻了,剪枝不了
  29. }
  30. return false;
  31. }
  32. //每个动物分配可以喂养(cnt>0),权重最大的人;贪心,这样后面的动物能够喂养的机会增大
  33. //证明: 对于某一个动物a,假如只能由某个人喂,那么他是唯一有权重的;
  34. //会不会出现这个人权值高但是后面某个动物b只能由这个人喂,所以为了节省cnt需要保留权值高的人,要选择权值低的人喂a呢?
  35. // 会。
  36. /*
  37. 1 1 1 1 0 1
  38. 1 1 1 0 1 0
  39. 每人最多喂3个
  40. 解是
  41. 1 1 1
  42. 1 1 1
  43. 但是根据贪心就失败了。所以这个贪心只是可以过但是是错的
  44. */
  45. bool greedy(){
  46. double maxcap=0;int per=-1,flag=-1;
  47. for(int i=0;i<animals;i++)
  48. {
  49. maxcap=0,per=-1,flag=0;
  50. for(int j=0;j<person;j++){ //
  51. if(capacity[j][i]>maxcap&&cnt[j]>0){ //常见错误,直接==0(double a>b) 应该用eps。但是这里数据在100,精度没那么高直接用也行
  52. per=j;flag=1;maxcap=capacity[j][i]; //常见错误 ij反了,注意意义!!。就是这里的i是animals而main中求cap的i是person,所以要反过来。所以要注意!!
  53. }
  54. }
  55. if(flag==0) return false; //常见错误 放错位置,注意在哪个结构({括号)
  56. cnt[per]--;
  57. }
  58. return true;
  59. }
  60. int main(){
  61. while(scanf("%d%d",&person,&animals)==2){
  62. for(int i=0;i<person;i++)
  63. for(int j=0;j<animals;j++)
  64. cin>>love[i][j]; //是否喜欢
  65. cin>>maxn;
  66. for(int i=0;i<person;i++)
  67. for(int j=0;j<animals;j++)
  68. used[i][j]==false;
  69. for(int i=0;i<person;i++) //每个人的上限
  70. cnt[i]=maxn;
  71. for(int i=0;i<person;i++) summ[i]=0; // 初始化
  72. for(int i=0;i<person;i++)
  73. for(int j=0;j<animals;j++)
  74. summ[i]+=love[i][j]; //每个人的总和
  75. for(int i=0;i<person;i++)
  76. for(int j=0;j<animals;j++)
  77. capacity[i][j] =1.0*love[i][j]/summ[i]; //权重
  78. if(greedy())
  79. cout<<"Yes"<<endl;
  80. else
  81. cout<<"No"<<endl;
  82. }
  83. return 0;
  84. }
  85. //2 网上还找到了网络流的做法 https://github.com/lijiansong/acm-algorithms/blob/master/CodeForces/woj/woj1008.cpp
  86. //好久没用,快忘了都
  87. //复习了紫书,感觉还是挺标准的
  88. 参考《算法竞赛入门经典》第11 网络流初步
  89. #include<iostream>
  90. #include<stdio.h>
  91. #include<string.h>
  92. #include<queue>
  93. #include<algorithm>
  94. using namespace std;
  95. #define N 210 //容量和流量之差=残量
  96. int m,n,k,a[N],flow[N][N],capacity[N][N],s,t,f,p[N]; //a[N]从起点到i的可改进量(可增量),也就是残量。残量是s 到i的路径上的最小残量,而非某条边
  97. void MaxFlow()
  98. {
  99. queue<int> q;
  100. memset(flow,0,sizeof(flow));
  101. f=0;
  102. for(;;)
  103. {
  104. memset(a,0,sizeof(a));
  105. a[s]=0xfffffff; //从外界到起点的流无限
  106. q.push(s);
  107. while(!q.empty())//BFS寻找增广路径
  108. {
  109. int u=q.front();
  110. q.pop();
  111. for(int v=1;v<=t;++v)
  112. {
  113. //找到新节点v
  114. if(!a[v] && capacity[u][v] > flow[u][v]) //残量>0 && 容量大于流量 .
  115. {
  116. p[v]=u;q.push(v);//记录v的父节点,并加入队列
  117. a[v]=min(a[u],capacity[u][v]-flow[u][v]);
  118. }
  119. }
  120. // if(a[t]) break;
  121. }
  122. if(a[t]==0)break;//s到t 残量为0,无法改进
  123. for(int u=t;u!=s;u=p[u])//从汇点往回走
  124. {
  125. flow[p[u]][u]+=a[t];//更新正向流量
  126. flow[u][p[u]]-=a[t];//更新反向流量
  127. }
  128. f+=a[t];//更新从s流出的总流量
  129. }
  130. }
  131. int main()
  132. {
  133. //freopen("in.txt","r",stdin);
  134. //freopen("out.txt","w",stdout);
  135. int i,j;
  136. while(cin>>m>>n)
  137. {
  138. memset(capacity,0,sizeof(capacity));
  139. s=0;
  140. t=m+n+1; //增加源点汇点 0 m+n+1 此时 m标号从1开始
  141. f=0; //总的流大小
  142. int ani=m+1,temp;
  143. for(i=1;i<=m;++i)
  144. {
  145. for(j=0;j<n;++j)
  146. {
  147. cin>>temp;
  148. if(temp==1)
  149. capacity[i][ani+j]=1;
  150. capacity[ani+j][t]=1; //反向边
  151. }
  152. }
  153. cin>>k;
  154. for(i=1;i<=m;++i)
  155. {
  156. capacity[0][i]=k; //源点到每个人的流大小为k,
  157. }
  158. MaxFlow();
  159. if(f==n)
  160. cout<<"Yes"<<endl;
  161. else
  162. cout<<"No"<<endl;
  163. }
  164. return 0;
  165. }

woj1008feedinganimals2-贪心-网络流的更多相关文章

  1. 【BZOJ3716】[PA2014]Muzeum(贪心+网络流)

    BZOJ 题意: 在二维网格图中有\(n\)个物品,每个物品有价值:但有\(m\)个警卫看管这些物品,每个警卫面朝\(y\)轴负方向,能看到一定角度(假定能够看到无穷远). 现在每个敬畏有一个贿赂价钱 ...

  2. 洛谷P1251 餐巾(网络流)

    P1251 餐巾 15通过 95提交 题目提供者该用户不存在 标签网络流贪心 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 为什么我全部10个测试点都对… 题目描述 一个餐厅在相继的N天里 ...

  3. 洛谷P2460 [SDOI2007]科比的比赛(题解)(贪心+搜索)

    科比的比赛(题解)(贪心+搜索) 标签:算法--贪心 阅读体验:https://zybuluo.com/Junlier/note/1301158 贪心+搜索 洛谷题目:P2460 [SDOI2007] ...

  4. 杭电ACM分类

    杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze ...

  5. 转自 Good morning 的几句精辟的话

    1.志愿者招募 根据流量平衡方程来构图非常方便,而且简单易懂,以后可能成为做网络流的神法之一 简单记一下流量平衡方程构图法的步骤: a.列出需求不等式 b.通过设置松弛变量,将不等式变成等式 c.两两 ...

  6. 【HDOJ】2732 Leapin' Lizards

    贪心+网络流.对于每个结点,构建入点和出点.对于每一个lizard>0,构建边s->in position of lizard, 容量为1.对于pillar>0, 构建边in pos ...

  7. 转载:hdu 题目分类 (侵删)

    转载:from http://blog.csdn.net/qq_28236309/article/details/47818349 基础题:1000.1001.1004.1005.1008.1012. ...

  8. bzoj3661

    网络流/贪心 网络流做法是对于每一列,如果一个兔子下一天继续可以存在,那么连一条容量为1的边,然后设立一个中转站,来控制可以换的数量,容量限制l.时限100s,能跑过去我的太慢了,一个点100s 正解 ...

  9. Color a Tree & 排列

    Color a Tree 题目链接 好不可做?可以尝试一下DP贪心网络流.DP 似乎没法做,网络流也不太行,所以试一下贪心. 考虑全局中最大权值的那个点,如果它没父亲,那么一定会先选它:否则,选完它父 ...

  10. 【CodeForces 589F】Gourmet and Banquet(二分+贪心或网络流)

    F. Gourmet and Banquet time limit per test 2 seconds memory limit per test 512 megabytes input stand ...

随机推荐

  1. AWS IoT Greengrass是什么?V1和V2版本及其差异

    AWS IoT Greengrass ​ Greengrass主要是用于边缘计算或者机器学习有关,对于详细了解请阅读结尾处的官方文档,文档内容也较为丰富. 目录 AWS IoT Greengrass ...

  2. java虚拟机入门(五)- 常见垃圾回收器及jvm实现

    上节讲完了垃圾回收的基础,包括java的垃圾是什么,如何寻找以及常用的垃圾回收算法,那么那么多的理论知识讲完了,具体是什么样的东西在做着回收垃圾的事情呢?我们接下来就好好聊聊jvm中常用的垃圾回收器. ...

  3. CACTI优化-流量接口统计total输入和输出流量数据

    看图,没有优化前(没有显示流入和流出的总流量是多少): 优化后(有显示流入和流出总流量统计): 如何实现呢?本节就是处理的过程小结.第一步:登陆cacti管理平台进入控制台->模板->图形 ...

  4. LVS负载均衡之DR模式原理介绍

    LVS基本原理 流程解释: 当用户向负载均衡调度器(Director Server)发起请求,调度器将请求发往至内核空间 PREROUTING 链首先会接收到用户请求,判断目标 IP 确定是本机 IP ...

  5. Java实现QQ邮件发送客户端

    目录 一.前言:QQ邮件发送程序 二.封装SMTP操作 三.实现多线程接收 四.QQ邮件客户端界面设计 1.连接按钮 2.发送按钮 五.QQ邮件发送效果演示 六.总结 一.前言:QQ邮件发送程序 在上 ...

  6. Sapphire: Copying GC Without Stopping the World

    https://people.cs.umass.edu/~moss/papers/jgrande-2001-sapphire.pdf Many concurrent garbage collectio ...

  7. 长连接开发踩坑之netty OOM问题排查实践

    https://mp.weixin.qq.com/s/jbXs7spUCbseMX-Vf43lPw 原创: 林健  51NB技术  2018-07-13

  8. TCMalloc源码学习(一)

    打算一边学习tcmalloc的源码一边写总结文章.先从转述TCMalloc的一篇官方文档开始(TCMalloc : Thread-Caching Malloc). 为什么用TCMalloc TCMal ...

  9. python atexit模块学习

    python atexit模块 只定义了一个register模块用于注册程序退出时的回调函数,我们可以在这个函数中做一下资源清理的操作 注:如果程序是非正常crash,或者通过os._exit()退出 ...

  10. css按钮样式

    style='height:22px;padding:1 17px;font-size: 8px;font-weight: 100;line-height: 25px;'http://www.boot ...