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 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的更多相关文章

  1. 1199 Problem B: 大小关系

    求有限集传递闭包的 Floyd Warshall 算法(矩阵实现) 其实就三重循环.zzuoj 1199 题 链接 http://acm.zzu.edu.cn:8000/problem.php?id= ...

  2. 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 ...

  3. C - NP-Hard Problem(二分图判定-染色法)

    C - NP-Hard Problem Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:262144 ...

  4. Time Consume Problem

    I joined the NodeJS online Course three weeks ago, but now I'm late about 2 weeks. I pay the codesch ...

  5. Programming Contest Problem Types

        Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...

  6. hdu1032 Train Problem II (卡特兰数)

    题意: 给你一个数n,表示有n辆火车,编号从1到n,入站,问你有多少种出站的可能.    (题于文末) 知识点: ps:百度百科的卡特兰数讲的不错,注意看其参考的博客. 卡特兰数(Catalan):前 ...

  7. BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】

    2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 4032  Solved: 1817[Submit] ...

  8. [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 ...

  9. [LeetCode] The Skyline Problem 天际线问题

    A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...

随机推荐

  1. 洛谷P1781 宇宙总统

    https://www.luogu.org/problem/show?pid=1781 高精比较大小: #include<iostream> #include<cstdio> ...

  2. 在前端解決顯示null值一例

    用.net core2.1 api返回的JSON里包含null值,前端直接顯示出來了,影響閱讀, 用以下語句將null轉換為空字符串: // Build html. html += "< ...

  3. JAVA基础之Properties类、序列化流及打印流、commons-IO

    个人理解: Properties类是个存储String类型的键值对的集合类,可以用其存储一些关键的账号密码什么的,同时后面的注释可以很好的帮助理解,但是需要注意的是其文件中不能出现其他的符号:序列化与 ...

  4. web常见几种处理图标方法

    方法一: 用background制作小图标 像这样,拿到设计稿后把所有的图标放在一张图片上,利用background-position.width.height来控制图标的位置及大小. 代码: .ic ...

  5. PHP 解决同一个IP不同端口号session冲突的问题

    在项目的开发阶段,我们经常会遇到几个站点共用同一个IP用不同端口号区分的形式!但是,这样很容易导致一个问题,session冲突丢失!即两个站点具有相同的session变量,清除session的时候即全 ...

  6. 日常-acm-韩信点兵

    相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排,五人一排,七人一排地变换队形,而他每次只看一眼队伍的排尾就知道人数了.输入包含多组数据,每组数据包含三个非负整数a,b,c,表示 ...

  7. .net 实现的上传下载,如果是图片就显示上传的图片

    HTML: <div> <input id="fileUpload" type="file" runat="server" ...

  8. 2019全套Java视频 免费赠送

    本人今年刚看完这套课程找到工作了 待遇还不错 现在送给大家 网盘链接:https://pan.baidu.com/s/1cEK6WoXS4F9SRgj1bZclqg提取码:bjl8希望对大家有用 一起 ...

  9. python之可迭代对象

    1. 可迭代对象是什么? 字面意思分析:可以重复的迭代的实实在在的东西 专业角度: 内部含有'__iter__'方法的对象,就是可迭代对象 2. 可迭代对象都有什么? list,dict(keys() ...

  10. javaweb基础(9)_Servlet生成验证码图片

    一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下: