题目大意:有n个人,已知每人有ki个糖纸,并且知道每张糖纸的颜色。其中,Bob希望能和同伴交换使得手上的糖纸数尽量多。他的同伴只会用手上的重复的交换手上没有的,并且他的同伴们之间不会产生交换。求出Bob能拥有的最大糖纸种数。

题目分析:对于Bob拥有的糖纸,从源点s连一条弧,容量为Bob拥有的数量;对于Bob的小伙伴,从Bob连一条弧向他拥有的糖纸,容量为拥有数量减1,对于他不拥有的糖纸,连一条有向弧从糖纸到他,容量为1;对于每一种糖纸,连一条弧向汇点t。最大流便是答案。

代码如下:

  1. # include<iostream>
  2. # include<cstdio>
  3. # include<cmath>
  4. # include<string>
  5. # include<vector>
  6. # include<list>
  7. # include<set>
  8. # include<map>
  9. # include<queue>
  10. # include<cstring>
  11. # include<algorithm>
  12. using namespace std;
  13.  
  14. # define LL long long
  15. # define REP(i,s,n) for(int i=s;i<n;++i)
  16. # define CL(a,b) memset(a,b,sizeof(a))
  17. # define CLL(a,b,n) fill(a,a+n,b)
  18.  
  19. const double inf=1e30;
  20. const int INF=1<<30;
  21. const int N=80;
  22.  
  23. struct Edge
  24. {
  25. int fr,to,cap,fw;
  26. Edge(int _fr,int _to,int _cap,int _fw):fr(_fr),to(_to),cap(_cap),fw(_fw){}
  27. };
  28. vector<Edge>edges;
  29. vector<int>G[N];
  30. int vis[N],d[N],cur[N],s,t,n,m,mark[30];
  31.  
  32. void init()
  33. {
  34. s=0,t=n+m+1;
  35. edges.clear();
  36. REP(i,0,t+1) G[i].clear();
  37. }
  38.  
  39. void addEdge(int u,int v,int cap)
  40. {
  41. edges.push_back(Edge(u,v,cap,0));
  42. edges.push_back(Edge(v,u,0,0));
  43. int len=edges.size();
  44. G[u].push_back(len-2);
  45. G[v].push_back(len-1);
  46. }
  47.  
  48. bool BFS()
  49. {
  50. queue<int>q;
  51. CL(vis,0);
  52. d[s]=0;
  53. vis[s]=1;
  54. q.push(s);
  55. while(!q.empty())
  56. {
  57. int x=q.front();
  58. q.pop();
  59. REP(i,0,G[x].size()){
  60. Edge &e=edges[G[x][i]];
  61. if(!vis[e.to]&&e.cap>e.fw){
  62. vis[e.to]=1;
  63. d[e.to]=d[x]+1;
  64. q.push(e.to);
  65. }
  66. }
  67. }
  68. return vis[t];
  69. }
  70.  
  71. int DFS(int x,int a)
  72. {
  73. if(x==t||a==0) return a;
  74. int flow=0,f;
  75. for(int &i=cur[x];i<G[x].size();++i){
  76. Edge &e=edges[G[x][i]];
  77. if(d[e.to]==d[x]+1&&(f=DFS(e.to,min(a,e.cap-e.fw)))>0){
  78. e.fw+=f;
  79. edges[G[x][i]^1].fw-=f;
  80. flow+=f;
  81. a-=f;
  82. if(a==0) break;
  83. }
  84. }
  85. return flow;
  86. }
  87.  
  88. int Dinic()
  89. {
  90. int flow=0;
  91. while(BFS()){
  92. CL(cur,0);
  93. flow+=DFS(s,INF);
  94. }
  95. return flow;
  96. }
  97.  
  98. int main()
  99. {
  100. int T,k,r,cas=0;
  101. scanf("%d",&T);
  102. while(T--)
  103. {
  104. scanf("%d%d",&n,&m);
  105. init();
  106. CL(mark,0);
  107. scanf("%d",&k);
  108. while(k--)
  109. {
  110. scanf("%d",&r);
  111. ++mark[r];
  112. }
  113. REP(i,1,m+1) if(mark[i]) addEdge(s,i,mark[i]);
  114. REP(i,1,n){
  115. CL(mark,0);
  116. scanf("%d",&k);
  117. while(k--){
  118. scanf("%d",&r);
  119. ++mark[r];
  120. }
  121. REP(j,1,m+1){
  122. if(mark[j]>=2) addEdge(m+i+1,j,mark[j]-1);
  123. else if(mark[j]==0) addEdge(j,m+i+1,1);
  124. }
  125. }
  126. REP(i,1,m+1) addEdge(i,t,1);
  127. printf("Case #%d: %d\n",++cas,Dinic());
  128. }
  129.   return 0;
  130. }

  

UVA-10779 Collectors Problem (网络流建模)的更多相关文章

  1. uva 10779 Collectors Problem 网络流

    链接 一共有n个人, m种收藏品, 每个人拥有的收藏品的种类和个数都是不相同的. 假设2-n这些人都只和1互相交换, 比例是1:1, 并且, 2-n这些人, 只换自己现在没有的, 如果他现在有第二种, ...

  2. UVA 10779 Collectors Problem(最大流)

    这个题是很难往网络流上面构思的... 从s向每个物品增加容量为Bob拥有数的弧,然后从每个物品向t增加容量为1的弧(代表种类个数).这时候跑最大流的话,得到的肯定是Bob拥有的初始种类数.那么交换后的 ...

  3. UVA 11082 矩阵解压(网络流建模)

    矩阵解压 紫书P374 建模真的是挺难的,如果直接给我这题,我是想不到用网络流的,所以还应多做网路流建模,学会如何转化成网络流 还有,现在用的EK算法是比较慢的,还应去看看Dnic和ISAP,并且理解 ...

  4. AC日记——Collectors Problem uva 10779

    UVA - 10779 思路: 最大流: s向所有的贴纸的种类连边,流量为Bob拥有的数量: 然后,Bob的朋友如果没有这种贴纸,则这种贴纸向bob的朋友连边,容量1: 如果bob的朋友的贴纸很多大于 ...

  5. UVA 10779 (最大流)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33631 题目大意:Bob有一些贴纸,他可以和别人交换,他可以把自己 ...

  6. UVA 10480 Sabotage (网络流,最大流,最小割)

    UVA 10480 Sabotage (网络流,最大流,最小割) Description The regime of a small but wealthy dictatorship has been ...

  7. uva 11991 - Easy Problem from Rujia Liu?(STL)

    option=com_onlinejudge&Itemid=8&page=show_problem&problem=3142" target="_blank ...

  8. CJOJ 2485 UVa 11991 生日礼物 / UVa 11991 Easy Problem from Rujia Liu?

    CJOJ 2485 UVa 11991 生日礼物 / UVa 11991 Easy Problem from Rujia Liu? Description (原题来自刘汝佳<训练指南>Pa ...

  9. 培训补坑(day4:网络流建模与二分图匹配)

    补坑时间到QAQ 好吧今天讲的是网络流建模与二分图匹配... day3的网络流建模好像说的差不多了.(囧) 那就接着补点吧.. 既然昨天讲了建图思想,那今天就讲讲网络流最重要的技巧:拆点. 拆点,顾名 ...

随机推荐

  1. oracle通过profile限制用户的恶意登录和使用期限

    用户profile口令管理 1,可以把profile想象成一个数据对象(文件,规则) 案例: 允许某用户,最多尝试登录3次,如3次未登录成功,则锁定该用户,锁定后两天不能登录系统 设置语法(syste ...

  2. Pycharm一直报ImportError: No module named requests

    1.首先检查是否安装了requests l 安装命令:pip install requests如果出现了Requirement already satisfied 代表安装成功 2.系统含有多个版本的 ...

  3. GraphicsMagick 号称图像处理领域的瑞士军刀

    标签: librarydelegatesimage图像处理fontstiff 2012-09-13 10:15 2496人阅读 评论(0) 收藏 举报  分类: java技术(52)  简介      ...

  4. scrapy爬虫系列之六--模拟登录

    功能点:如何发送携带cookie访问登录后的页面,如何发送post请求登录 爬取网站:bilibili.github 完整代码:https://files.cnblogs.com/files/book ...

  5. ping 10.13.5.233

    3. 环境 URL选择器 tableView ping 10.13.5.233

  6. 用 mongodb 储存多态消息/提醒类数据(转)

    原文:http://codecampo.com/topics/66 前天看到 javaeye 计划采用mongoDB实现网站全站消息系统,很有同感,mongodb 很适合储存消息类数据.之前讨论了如何 ...

  7. SqlServer PIVOT函数快速实现行转列,UNPIVOT实现列转行(转)

    我们在写Sql语句的时候没经常会遇到将查询结果行转列,列转行的需求,拼接sql字符串,然后使用sp_executesql执行sql字符串是比较常规的一种做法.但是这样做实现起来非常复杂,而在SqlSe ...

  8. Hadoop MapReduce Task的进程模型与Spark Task的线程模型

    Hadoop的MapReduce的Map Task和Reduce Task都是进程级别的:而Spark Task则是基于线程模型的. 多进程模型和多线程模型 所谓的多进程模型和多线程模型,指的是同一个 ...

  9. 【转】Deep Learning(深度学习)学习笔记整理系列之(一)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0  2013-0 ...

  10. testng生成报告ReportNG美化测试报告

    testng生成报告ReportNG美化测试报告 testng生成报告ReportNG美化测试报告 ReportNG 是一个配合TestNG运行case后自动帮你在test-output文件内生成一个 ...