题目链接:https://cn.vjudge.net/problem/UVA-10779

前言:

  本题是关于姜志豪《网络流的一些建模方法》的笔记。

知识点:  最大流

题意摘抄:

  \(Bob\) 和他的朋友从糖果包装里收集贴纸。\(Bob\) 和他的朋友总共 \(n\) 人。共有 \(m\) 种不同的贴纸。

  每人手里都有一些(可能有重复的)贴纸,并且只跟别人交换他所没有的贴纸。贴纸总是一对一交换。

  \(Bob\) 比这些朋友更聪明,因为他意识到只跟别人交换自己没有的贴纸并不总是最优的。在某些情况下,换来一张重复贴纸更划算。

  假设 \(Bob\) 的朋友只和 \(Bob\) 交换(他们之间不交换),并且这些朋友只会出让手里的重复贴纸来交换他们没有的不同贴纸。你的任务是帮助 \(Bob\) 算出他最终可以得到的不同贴纸的最大数量。

  \((2 \le n le 10, 5 \le m \le 25)\)

解题思路:

  每种贴纸、每个朋友都各视为一个点,再加上一个源点和一个汇点。

  对于每种贴纸,建一条从源点到这种贴纸的边,容量为 \(Bob\) 所拥有的这种贴纸的张数;

  对于每一个朋友,如果他没有某种贴纸,就建一条从这种贴纸到他的边,容量为 \(1\);如果他有这种贴纸并且拥有量 \(k\) 大于\(1\) ,则建一条从他到这种贴纸的边,容量为 \(k-1\).

  对于每种贴纸,再建一条边到汇点,容量为 \(1\).

AC代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int MAXN = ;//点数的最大值
  4. const int MAXM = ;//边数的最大值
  5. const int INF = 0x3f3f3f3f;
  6.  
  7. struct Edge{
  8. int to,next,cap,flow;
  9. }edge[MAXM];//注意是MAXM
  10. int tol;
  11. int head[MAXN];
  12. int gap[MAXN],dep[MAXN],cur[MAXN];
  13. void init(){
  14. tol = ;
  15. memset(head,-,sizeof(head));
  16. }
  17. void addedge(int u,int v,int w,int rw = ){
  18. edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = ;
  19. edge[tol].next = head[u]; head[u] = tol++;
  20. edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = ;
  21. edge[tol].next = head[v]; head[v] = tol++;
  22. }
  23. int Q[MAXN];
  24. void BFS(int start,int end){
  25. memset(dep,-,sizeof(dep));
  26. memset(gap,,sizeof(gap));
  27. gap[] = ;
  28. int front = , rear = ;
  29. dep[end] = ;
  30. Q[rear++] = end;
  31. while(front != rear){
  32. int u = Q[front++];
  33. for(int i = head[u]; i != -; i = edge[i].next){
  34. int v = edge[i].to;
  35. if(dep[v] != -)
  36. continue;
  37. Q[rear++] = v;
  38. dep[v] = dep[u] + ;
  39. gap[dep[v]]++;
  40. }
  41. }
  42. }
  43. int S[MAXN];
  44. int sap(int start,int end,int N){
  45. BFS(start,end);
  46. memcpy(cur,head,sizeof(head));
  47. int top = ;
  48. int u = start;
  49. int ans = ;
  50. while(dep[start] < N){
  51. if(u == end){
  52. int Min = INF;
  53. int inser;
  54. for(int i = ;i < top;i++)
  55. if(Min > edge[S[i]].cap - edge[S[i]].flow){
  56. Min = edge[S[i]].cap - edge[S[i]].flow;
  57. inser = i;
  58. }
  59. for(int i = ;i < top;i++){
  60. edge[S[i]].flow += Min;
  61. edge[S[i]^].flow -= Min;
  62. }
  63. ans += Min;
  64. top = inser;
  65. u = edge[S[top]^].to;
  66. continue;
  67. }
  68. bool flag = false;
  69. int v;
  70. for(int i = cur[u]; i != -; i = edge[i].next){
  71. v = edge[i].to;
  72. if(edge[i].cap - edge[i].flow && dep[v]+ == dep[u]){
  73. flag = true;
  74. cur[u] = i;
  75. break;
  76. }
  77. }
  78. if(flag){
  79. S[top++] = cur[u];
  80. u = v;
  81. continue;
  82. }
  83. int Min = N;
  84. for(int i = head[u]; i != -; i = edge[i].next)
  85. if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min){
  86. Min = dep[edge[i].to];
  87. cur[u] = i;
  88. }
  89. gap[dep[u]]--;
  90. if(!gap[dep[u]])
  91. return ans;
  92. dep[u] = Min + ;
  93. gap[dep[u]]++;
  94. if(u != start)
  95. u = edge[S[--top]^].to;
  96. }
  97. return ans;
  98. }
  99. int has[];
  100. int main(){
  101. int T;
  102. int n,m,k;
  103. int num;
  104. int kase=;
  105. scanf("%d",&T);
  106. while(T--){
  107. init();
  108. int s=,t=MAXN-;
  109. memset(has,,sizeof(has));
  110. scanf("%d%d",&n,&m);
  111. scanf("%d",&k);
  112. while(k--){
  113. scanf("%d",&num);
  114. has[num]++;
  115. }
  116. for(int i=;i<=m;i++){
  117. addedge(s,i,has[i]);
  118. addedge(i,t,);
  119. }
  120. for(int i=;i<n;i++){
  121. memset(has,,sizeof(has));
  122. scanf("%d",&k);
  123. while(k--){
  124. scanf("%d",&num);
  125. has[num]++;
  126. }
  127. for(int j=;j<=m;j++){
  128. if(!has[j])
  129. addedge(j,+i,);
  130. else if(has[j]>)
  131. addedge(+i,j,has[j]-);
  132. }
  133. }
  134. printf("Case #%d: %d\n",kase++,sap(s,t,+m+n));
  135. }
  136. return ;
  137. }

UVA10779 Collectors Problem的更多相关文章

  1. UVA-10779 Collectors Problem

    https://vjudge.net/problem/UVA-10779 题意:n个人,m种贴纸,每个人开始有一些贴纸 第一个人可以跟任何人交换任何贴纸 其余人只能用重复的贴纸 跟第一个人交换他们没有 ...

  2. UVa10779 Collectors Problem(最大流)

    很容易想到源点向所类型有贴纸连边,容量为Bob一开始有的数量:然后贴纸向汇点连边,容量为1. 接下来就是交换部分的连边了.注意交换一次一次进行,每次只能交换一张. 交换,是对于两种贴纸而言,仅会发生在 ...

  3. UVA-10779 Collectors Problem (网络流建模)

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

  4. UVA10779 Collectors Problem 【迁移自洛谷博客】

    这是一道不错的练最大流建模的基础题. 这种题目审题是关键. Bob's friends will only exchange stickers with Bob, and they will give ...

  5. [Bob]Collectors Problem

    https://vjudge.net/problem/UVA-10779#author=0 网络流 1.Bob向他有的贴纸连边,流量为他有的贴纸数量 2.每一种贴纸向汇点连流量为1的边 3.其余人,如 ...

  6. UVA 10779 Collectors Problem(最大流)

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

  7. uva 10779 Collectors Problem 网络流

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

  8. AC日记——Collectors Problem uva 10779

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

  9. UVA10779Collectors Problem

    uva 10779 Collectors Problem Some candy manufacturers put stickers into candy bar packages. Bob and ...

随机推荐

  1. c++ 如何开N次方?速解

    c++ 如何开N次方?速解   直接上代码 #include <iostream> #include <cmath> using namespace std; typedef ...

  2. Python语言类型

    Python是一门动态解释型的强类型语言. 对这句话进行解析,语言分为动态的和静态的,编译型和解释型的,强类型的和弱类型的语言之分. 下面对三种不同维度的类型的语言进行解释: 1.编译型和解释型 差别 ...

  3. 记一次Pinpoint监控工具部署过程

    环境:Centos 7.4 X64IP:192.168.1.11 1.配置环境,先安装jdk 到Oracle官网下载安装JDK https://www.oracle.com/technetwork/j ...

  4. 信息奥赛一本通1486: CH 6202 黑暗城堡 最短路径生成树计数

    1486:黑暗城堡 [题目描述] 知道黑暗城堡有 N 个房间,M 条可以制造的双向通道,以及每条通道的长度. 城堡是树形的并且满足下面的条件: 设 Di为如果所有的通道都被修建,第 i 号房间与第 1 ...

  5. P1516 青蛙的约会和P2421 [NOI2002]荒岛野人

    洛谷 P1516 青蛙的约会 . 算是手推了一次数论题,以前做的都是看题解,虽然这题很水而且还交了5次才过... 求解方程\(x+am\equiv y+an \pmod l\)中,\(a\)的最小整数 ...

  6. python(字符编码与转码)

    一.字符编码演变史 二进制(0 1) """ 算机中的所有数据,不论是文字.图片.视频.还是音频文件,本质上最终都是按照类似 01010101 的二进制存储的,再说简单点 ...

  7. 学习笔记之MySQL的使用

    什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库. 每个数据库都有一个或多个不同的 API 用于创建,访问,管理,搜索和复制所保存的数据. 我们也可以将数据存储在文 ...

  8. 域名系统(DNS)初探

    1.定义 域名:又称网域,是由一串用点分隔的名字组成的Internet上某一台计算机或计算机组的名称(如mail.cctv.com),用于在数据传输时对计算机的定位标识(有时也指地理位置): 域名系统 ...

  9. 化妆品行业的一个MES系统案例(三)

    项目的主要需求如下: (1) 管理产品的配方(物料BOM) (2) 管理产品的生产工艺(最终要将工艺参数下发到设备PLC自动执行) (3) 根据生产工单集合产品配方生成称量任务(其实领料之后的成料过程 ...

  10. mac下xampp使用phpmyadmin搭建后台

    情景 使用xampp搭建一个后端环境,前提已经有后端和数据库配置文件 安装和启动xampp 安装xampp没什么可说的,在https://www.apachefriends.org/index.htm ...