zoukankan      html  css  js  c++  java
  • 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 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

      1 include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<iostream>
      6 
      7 using namespace std;
      8 
      9 const int INF = 1e9;
     10 const int N = 10010;
     11 
     12 struct Edge{
     13     int to,nxt,c;
     14 }e[N];
     15 int q[500100],head[N],cur[N],dis[N],cnt[50][50];
     16 int L,R,S,T,tot = 1;
     17 
     18 inline char nc() {
     19     static char buf[100000],*p1 = buf,*p2 = buf;
     20     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
     21 }
     22 inline int read() {
     23     int x = 0,f = 1;char ch = nc();
     24     for (; ch<'0'||ch>'9'; ch = nc()) if (ch=='-') f = -1;
     25     for (; ch>='0'&&ch<='9'; ch = nc()) x = x * 10 + ch - '0';
     26     return x * f;
     27 }
     28 inline void init() {
     29     tot = 1;memset(head,0,sizeof(head));
     30     memset(cnt,0,sizeof(cnt));
     31 }
     32 inline void add_edge(int u,int v,int w) {
     33     e[++tot].to = v,e[tot].c = w,e[tot].nxt = head[u],head[u] = tot;
     34     e[++tot].to = u,e[tot].c = 0,e[tot].nxt = head[v],head[v] = tot;
     35 }
     36 bool bfs() {
     37     for (int i=1; i<=T; ++i) {
     38         cur[i] = head[i];dis[i] = -1;
     39     }
     40     L = 1;R = 0;
     41     q[++R] = S;
     42     dis[S] = 0;
     43     while (L <= R) {
     44         int u = q[L++];
     45         for (int i=head[u]; i; i=e[i].nxt) {
     46             int v = e[i].to,c = e[i].c;
     47             if (dis[v]==-1&&c>0) {
     48                 dis[v] = dis[u] + 1;
     49                 q[++R] = v;
     50                 if (v==T) return true;
     51             }
     52         }
     53     }
     54     return false;
     55 }
     56 int dfs(int u,int flow) {
     57     if (u==T) return flow;
     58     int used = 0;
     59     for (int &i=cur[u]; i; i=e[i].nxt) {
     60         int v = e[i].to,c = e[i].c;
     61         if (dis[v]==dis[u]+1 && c>0) {
     62             int tmp = dfs(v,min(c,flow-used));
     63             if (tmp > 0) {
     64                 e[i].c -= tmp;e[i^1].c += tmp;
     65                 used += tmp;
     66                 if (used==flow) break;
     67             }
     68         }
     69     }
     70     if (used!=flow) dis[u] = -1;
     71     return used;
     72 }
     73 inline int dinic() {
     74     int ans = 0;
     75     while (bfs()) ans += dfs(S,INF);
     76     return ans;
     77 }
     78 int main() {
     79     int sum_case = read();
     80     for (int Case=1; Case<=sum_case; Case++) {
     81         init();
     82         int n = read(),m = read();
     83         S = 1;T = n + m + 1;
     84         for (int i=1; i<=m; ++i) add_edge(i+n,T,1);
     85         for (int i=1; i<=n; ++i) {
     86             int k = read();
     87             for (int a,j=1; j<=k; ++j) {
     88                 a = read();cnt[i][a]++;
     89             }
     90         }
     91         for (int i=1; i<=m; ++i) 
     92             if (cnt[1][i]) add_edge(S,i+n,cnt[1][i]);
     93         for (int i=2; i<=n; ++i) {
     94             for (int j=1; j<=m; ++j) {
     95                 if (cnt[i][j] > 1) add_edge(i,j+n,cnt[i][j]-1);
     96                 else if (cnt[i][j]==0) add_edge(j+n,i,1);
     97             }
     98         }
     99         printf("Case #%d: %d
    ",Case,dinic());        
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    lock free
    Solr 开发环境搭建
    Web中实现网页跳转的方法大总结:
    CSS定位中最难理解的她——absolute的探讨
    JavaScript中正则表达式中遇到的问题——测试匹配
    编写一个Android平台遇到的所有问题(一)——查询sqlite数据库时遇到的问题
    初来乍到,大家好
    在stackoverflow上使用markdown
    提升debian中字体效果
    vim pathogen自动配置
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8093574.html
Copyright © 2011-2022 走看看