UVA10779Collectors Problem
uva 10779 Collectors Problem
Some candy manufacturers put stickers into candy bar packages. Bob and his friends are collecting
these stickers. They all want as many different stickers as possible, but when they buy a candy bar,
they don’t know which sticker is inside.
It happens that one person has duplicates of a certain sticker. Everyone trades duplicates for stickers
he doesn’t possess. Since all stickers have the same value, the exchange ratio is always 1:1.
But Bob is clever: he has realized that in some cases it is good for him to trade one of his duplicate
stickers for a sticker he already possesses.
Now assume, Bob’s friends will only exchange stickers with Bob, and they will give away only
duplicate stickers in exchange with different stickers they don’t possess.
Can you help Bob and tell him the maximum number of different stickers he can get by trading
stickers with his friends?
Input
The first line of input contains the number of cases T (T ≤ 20). The first line of each case contains
two integers n and m (2 ≤ n ≤ 10, 5 ≤ m ≤ 25). n is the number of people involved (including Bob),
and m is the number of different stickers available.
The next n lines describe each person’s stickers; the first of these lines describes Bob’s stickers.
The i-th of these lines starts with a number ki ≤ 50 indicating how many stickers person i has.
Then follows ki numbers between 1 and m indicating which stickers person i possesses.
Output
For each case, print the test case number together with the maximum number of different stickers Bob
can get.
Explanation of the sample output:
In the first case, no exchange is possible, therefore Bob can have only the sticker with number 1.
In the second case, Bob can exchange a sticker with number 1 against a sticker with number 2 of
the second person, and then this sticker against a sticker with number 3 or 4 of the third person, and
now he has stickers 1, 2 and 3 or 1, 2 and 4.
Sample Input
2
2 5
6 1 1 1 1 1 1
3 1 2 2
3 5
4 1 2 1 1
3 2 2 2
5 1 3 4 4 3
Sample Output
Case #1: 1
Case #2: 3
题意
n个人,m种贴纸,每个人开始都有一些贴纸。
第一个人Bob可以跟任何人交换任何贴纸,其他人只能用重复的贴纸,和Bob交换他们没有的贴纸,Bob最后最多有多少种贴纸
分析
网络流。重点是建图。
Bob做源点好了,汇点新建一个。
Bob和所有贴纸有一条流量为 Bob拥有的贴纸数量的边,所有贴纸都与汇点建一条流量为1的边。
如果其他的人第i张贴纸有x张多余的,那么这个人向i连一条流量为x的边。
如果他第i张贴纸为0,那么i向这个人连一条流量为1的边。
code
- include<cstdio>
- #include<algorithm>
- #include<cstring>
- #include<cmath>
- #include<iostream>
- using namespace std;
- const int INF = 1e9;
- const int N = ;
- struct Edge{
- int to,nxt,c;
- }e[N];
- int q[],head[N],cur[N],dis[N],cnt[][];
- int L,R,S,T,tot = ;
- inline char nc() {
- static char buf[],*p1 = buf,*p2 = buf;
- return p1==p2&&(p2=(p1=buf)+fread(buf,,,stdin),p1==p2)?EOF:*p1++;
- }
- inline int read() {
- int x = ,f = ;char ch = nc();
- for (; ch<''||ch>''; ch = nc()) if (ch=='-') f = -;
- for (; ch>=''&&ch<=''; ch = nc()) x = x * + ch - '';
- return x * f;
- }
- inline void init() {
- tot = ;memset(head,,sizeof(head));
- memset(cnt,,sizeof(cnt));
- }
- inline void add_edge(int u,int v,int w) {
- e[++tot].to = v,e[tot].c = w,e[tot].nxt = head[u],head[u] = tot;
- e[++tot].to = u,e[tot].c = ,e[tot].nxt = head[v],head[v] = tot;
- }
- bool bfs() {
- for (int i=; i<=T; ++i) {
- cur[i] = head[i];dis[i] = -;
- }
- L = ;R = ;
- q[++R] = S;
- dis[S] = ;
- while (L <= R) {
- int u = q[L++];
- for (int i=head[u]; i; i=e[i].nxt) {
- int v = e[i].to,c = e[i].c;
- if (dis[v]==-&&c>) {
- dis[v] = dis[u] + ;
- q[++R] = v;
- if (v==T) return true;
- }
- }
- }
- return false;
- }
- int dfs(int u,int flow) {
- if (u==T) return flow;
- int used = ;
- for (int &i=cur[u]; i; i=e[i].nxt) {
- int v = e[i].to,c = e[i].c;
- if (dis[v]==dis[u]+ && c>) {
- int tmp = dfs(v,min(c,flow-used));
- if (tmp > ) {
- e[i].c -= tmp;e[i^].c += tmp;
- used += tmp;
- if (used==flow) break;
- }
- }
- }
- if (used!=flow) dis[u] = -;
- return used;
- }
- inline int dinic() {
- int ans = ;
- while (bfs()) ans += dfs(S,INF);
- return ans;
- }
- int main() {
- int sum_case = read();
- for (int Case=; Case<=sum_case; Case++) {
- init();
- int n = read(),m = read();
- S = ;T = n + m + ;
- for (int i=; i<=m; ++i) add_edge(i+n,T,);
- for (int i=; i<=n; ++i) {
- int k = read();
- for (int a,j=; j<=k; ++j) {
- a = read();cnt[i][a]++;
- }
- }
- for (int i=; i<=m; ++i)
- if (cnt[][i]) add_edge(S,i+n,cnt[][i]);
- for (int i=; i<=n; ++i) {
- for (int j=; j<=m; ++j) {
- if (cnt[i][j] > ) add_edge(i,j+n,cnt[i][j]-);
- else if (cnt[i][j]==) add_edge(j+n,i,);
- }
- }
- printf("Case #%d: %d\n",Case,dinic());
- }
- return ;
- }
UVA10779Collectors Problem的更多相关文章
- 1199 Problem B: 大小关系
求有限集传递闭包的 Floyd Warshall 算法(矩阵实现) 其实就三重循环.zzuoj 1199 题 链接 http://acm.zzu.edu.cn:8000/problem.php?id= ...
- No-args constructor for class X does not exist. Register an InstanceCreator with Gson for this type to fix this problem.
Gson解析JSON字符串时出现了下面的错误: No-args constructor for class X does not exist. Register an InstanceCreator ...
- C - NP-Hard Problem(二分图判定-染色法)
C - NP-Hard Problem Crawling in process... Crawling failed Time Limit:2000MS Memory Limit:262144 ...
- Time Consume Problem
I joined the NodeJS online Course three weeks ago, but now I'm late about 2 weeks. I pay the codesch ...
- Programming Contest Problem Types
Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...
- hdu1032 Train Problem II (卡特兰数)
题意: 给你一个数n,表示有n辆火车,编号从1到n,入站,问你有多少种出站的可能. (题于文末) 知识点: ps:百度百科的卡特兰数讲的不错,注意看其参考的博客. 卡特兰数(Catalan):前 ...
- BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】
2301: [HAOI2011]Problem b Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 4032 Solved: 1817[Submit] ...
- [LeetCode] Water and Jug Problem 水罐问题
You are given two jugs with capacities x and y litres. There is an infinite amount of water supply a ...
- [LeetCode] The Skyline Problem 天际线问题
A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...
随机推荐
- Win7环境下配置FTP
1.打开 控制面板-->程序和功能-->打开或关闭Windows资源,在弹出的窗体里找到 “Internet信息服务”,展开后选择“Ftp服务器",然后点击"确定&qu ...
- iOS-浅谈runtime运行时机制02-runtime简单使用
http://blog.csdn.net/jiajiayouba/article/details/44201079 由于OC是运行时语言,只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方 ...
- [LR]遇到的坑及常用技巧
解决问题是需要智慧的 1.LR内部问题可以查看帮助文档 一般位于LR安装目录的bin目录下,如下图 打开Troubleshooting.chm文件,比如我们跑场景的过程中报错,报错信息为:-27995 ...
- 在SAP C4C里触发SAP ERP的ATP check和Credit check
在C4C里创建一个新的Sales Quote: 添加三个行项目: 执行action "Request External Pricing"会从ERP更新pricing信息,触发ATP ...
- 如何真正解决“ UWP DEP0700: 应用程序注册失败。[0x80073CF9] 另一个用户已安装此应用的未打包版本。当前用户无法将该...”的问题
http://www.cnblogs.com/hupo376787/p/8267796.html 谈到了解决该问题的临时方案,那如何真正的解决该问题 目测可以开启设备门户来删除包
- vue-cli版本更新(2.9.1)问题记录-2
今天想把做好的页面放在手机端浏览,发现新版的vue-cli无论在PC还是手机都只能用localhost访问(127.0.0.1除外).....(这样还怎么让我用手机吃鸡了!TT),于是我在网上查找了一 ...
- UVA 1471 Defense Lines 防线 (LIS变形)
给一个长度为n的序列,要求删除一个连续子序列,使剩下的序列有一个长度最大的连续递增子序列. 最简单的想法是枚举起点j和终点i,然后数一数,分别向前或向后能延伸的最长长度,记为g(i)和f(i).可以先 ...
- Android(java)学习笔记125:保存数据到SD卡 (附加:保存数据到内存)
1. 如果我们要想读写数据到SD卡中,首先必须知道SD的路径: File file = new File(Environment.getExternalStorageDirectory()," ...
- Beta冲刺(周五)
这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1 这个作业要求在哪里 https://edu.cnblo ...
- CPP-基础:C/C++数组名与指针的区别
2005-08-23 08:36 来源:天极网 作者:宋宝华 责任编辑:方舟·yesky 引言 指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用.于是乎,很 ...