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. pytorch 0.3 win7 安装

    pytorch 0.3 win7 安装 参考这个文章:https://github.com/peterjc123/pytorch-scripts 首先安装 conda 这个链接下载: python 3 ...

  2. [20190620]日常学习记录(三)-初识promise及vuex

    在学习promise之前重温了Ajax的原生js实现, 在原生js中发送一个http请求首先new XMLHttpRequest() 然后定义状态变更事件 浏览器监听请求的状态,触发不同状态下相应的代 ...

  3. ios获取数据之encodeURI 和 decodeURI

    在APP开发过程中,免不了要进行ios的数据处理,在ios传递数据的过程中,会出现JSON数据获取不到的情况,这时候就轮到encodeURI 和 decodeURI出马了. 1.encodeURI,d ...

  4. window.open()弹出窗口参数说明及居中设置

    window.open()可以弹出一个新的窗口,并且通过参数控制窗口的各项属性. 最基本的弹出窗口代码 window.open('httP://codeo.cn/'); window.open()各参 ...

  5. Android Studio maven-metadata.xml 卡着不动原因和解决方法

    头一天好好的,第二天就卡着了. 一直在这个地方不动,如果停止就会报 Error:Could not run build action using Gradle distribution ‘https: ...

  6. java 通过文件后缀名查找文件

    最近开发项目的时候需要过滤出一些指定的文件,所以有了以下的一些代码: /** **该类主要是过滤得到指定后缀名的文件 **/ public class DataFileFilter implement ...

  7. Python3获取大量电影信息:调用API

    实验室这段时间要采集电影的信息,给出了一个很大的数据集,数据集包含了4000多个电影名,需要我写一个爬虫来爬取电影名对应的电影信息. 其实在实际运作中,根本就不需要爬虫,只需要一点简单的Python基 ...

  8. Codeforces Round #320 (Div. 1) [Bayan Thanks-Round] B "Or" Game (贪心)

    首先应该保证二进制最高位尽量高,而位数最高的数乘x以后位数任然是最高的,所以一定一个数是连续k次乘x. 当出现多个最高位的相同的数就枚举一下,先预处理一下前缀后缀即可. #include<bit ...

  9. Codeforces Round #320 (Div. 1) [Bayan Thanks-Round] A A Problem about Polyline(数学)

    题目中给出的函数具有周期性,总可以移动到第一个周期内,当然,a<b则无解. 假设移动后在上升的那段,则有a-2*x*n=b,注意限制条件x≥b,n是整数,则n≤(a-b)/(2*b).满足条件的 ...

  10. UVA 1623 Enther the Dragon 神龙喝水 (贪心)

    贪心,每次遇到一个满水的湖要下暴雨的时候,就往前找之前最后一次满水之后的第一个没有下雨的且没有被用掉天day1. 因为如果不选这day1,那么之后的湖不一定能选上这一天.如果这一天后面还有没有下雨的天 ...