zoukankan      html  css  js  c++  java
  • BZOJ 1711: [Usaco2007 Open]Dining吃饭

    1711: [Usaco2007 Open]Dining吃饭

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 902  Solved: 476
    [Submit][Status][Discuss]

    Description

    农夫JOHN为牛们做了很好的食品,但是牛吃饭很挑食. 每一头牛只喜欢吃一些食品和饮料而别的一概不吃.虽然他不一定能把所有牛喂饱,他还是想让尽可能多的牛吃到他们喜欢的食品和饮料. 农夫JOHN做了F (1 <= F <= 100) 种食品并准备了D (1 <= D <= 100) 种饮料. 他的N (1 <= N <= 100)头牛都以决定了是否愿意吃某种食物和喝某种饮料. 农夫JOHN想给每一头牛一种食品和一种饮料,使得尽可能多的牛得到喜欢的食物和饮料. 每一件食物和饮料只能由一头牛来用. 例如如果食物2被一头牛吃掉了,没有别的牛能吃食物2.

    Input

    * 第一行: 三个数: N, F, 和 D

    * 第2..N+1行: 每一行由两个数开始F_i 和 D_i, 分别是第i 头牛可以吃的食品数和可以喝的饮料数.下F_i个整数是第i头牛可以吃的食品号,再下面的D_i个整数是第i头牛可以喝的饮料号码.

    Output

    * 第一行: 一个整数,最多可以喂饱的牛数.

    Sample Input

    4 3 3
    2 2 1 2 3 1
    2 2 2 3 1 2
    2 2 1 3 1 2
    2 1 1 3 3

    输入解释:

    牛 1: 食品从 {1,2}, 饮料从 {1,2} 中选
    牛 2: 食品从 {2,3}, 饮料从 {1,2} 中选
    牛 3: 食品从 {1,3}, 饮料从 {1,2} 中选
    牛 4: 食品从 {1,3}, 饮料从 {3} 中选

    Sample Output

    3
    输出解释:

    一个方案是:
    Cow 1: 不吃
    Cow 2: 食品 #2, 饮料 #2
    Cow 3: 食品 #1, 饮料 #1
    Cow 4: 食品 #3, 饮料 #3
    用鸽笼定理可以推出没有更好的解 (一共只有3总食品和饮料).当然,别的数据会更难.

    HINT

     

    Source

    [Submit][Status][Discuss]

    网络流,拆点建图,每一条流都对应着满足一头牛的方案。和今天考试T1贼像……

      1 #include <cstdio>
      2 
      3 inline int nextChar(void) {
      4     const int siz = 1024;
      5     
      6     static char buf[siz];
      7     static char *hd = buf + siz;
      8     static char *tl = buf + siz;
      9     
     10     if (hd == tl)
     11         fread(hd = buf, 1, siz, stdin);
     12         
     13     return *hd++;
     14 }
     15  
     16 inline int nextInt(void) {
     17     register int ret = 0;
     18     register int neg = false;
     19     register int bit = nextChar();
     20     
     21     for (; bit < 48; bit = nextChar())
     22         if (bit == '-')neg ^= true;
     23         
     24     for (; bit > 47; bit = nextChar())
     25         ret = ret * 10 + bit - 48;
     26         
     27     return neg ? -ret : ret;
     28 }
     29 
     30 inline int min(int a, int b)
     31 {
     32     return a < b ? a : b;
     33 }
     34 
     35 const int siz = 500005;
     36 const int inf = 1000000007;
     37 
     38 int tot;
     39 int s, t;
     40 int hd[siz];
     41 int to[siz];
     42 int fl[siz];
     43 int nt[siz];
     44 
     45 inline void add(int u, int v, int f)
     46 {
     47     nt[tot] = hd[u]; to[tot] = v; fl[tot] = f; hd[u] = tot++;
     48     nt[tot] = hd[v]; to[tot] = u; fl[tot] = 0; hd[v] = tot++;
     49 }
     50 
     51 int dep[siz];
     52 
     53 inline bool bfs(void)
     54 {
     55     static int que[siz], head, tail;
     56     
     57     for (int i = s; i <= t; ++i)dep[i] = 0;
     58     
     59     dep[que[head = 0] = s] = tail = 1;
     60     
     61     while (head != tail)
     62     {
     63         int u = que[head++], v;
     64         
     65         for (int i = hd[u]; ~i; i = nt[i])
     66             if (!dep[v = to[i]] && fl[i])
     67                 dep[que[tail++] = v] = dep[u] + 1;
     68     }
     69     
     70     return dep[t];
     71 }
     72 
     73 int cur[siz];
     74 
     75 int dfs(int u, int f)
     76 {
     77     if (u == t || !f)
     78         return f;
     79         
     80     int used = 0, flow, v;
     81     
     82     for (int i = cur[u]; ~i; i = nt[i])
     83         if (dep[v = to[i]] == dep[u] + 1 && fl[i])
     84         {
     85             flow = dfs(v, min(fl[i], f - used));
     86             
     87             used += flow;
     88             fl[i] -= flow;
     89             fl[i^1] += flow;
     90             
     91             if (used == f)
     92                 return f;
     93             
     94             if (fl[i])
     95                 cur[u] = i;
     96         }
     97         
     98     if (!used)
     99         dep[u] = 0;
    100     
    101     return used;
    102 }
    103 
    104 inline int maxFlow(void)
    105 {
    106     int maxFlow = 0, newFlow;
    107     
    108     while (bfs())
    109     {
    110         for (int i = s; i <= t; ++i)
    111             cur[i] = hd[i];
    112         
    113         while (newFlow = dfs(s, inf))
    114             maxFlow += newFlow;
    115     }
    116     
    117     return maxFlow;
    118 }
    119 
    120 int N, F, D;
    121 
    122 inline int cow(int x, int y)
    123 {
    124     return F + D + y * N + x;
    125 }
    126 
    127 inline int food(int x)
    128 {
    129     return x;
    130 }
    131 
    132 inline int drink(int x)
    133 {
    134     return x + F;
    135 }
    136 
    137 signed main(void)
    138 {
    139     N = nextInt();
    140     F = nextInt();
    141     D = nextInt();
    142     
    143     s = 0, t = N*2 + F + D + 1;
    144     
    145     for (int i = s; i <= t; ++i)
    146         hd[i] = -1;
    147         
    148     for (int i = 1; i <= F; ++i)
    149         add(s, food(i), 1);
    150         
    151     for (int i = 1; i <= D; ++i)
    152         add(drink(i), t, 1);
    153         
    154     for (int i = 1; i <= N; ++i)
    155     {
    156         int f = nextInt();
    157         int d = nextInt();
    158         
    159         add(cow(i, 0), cow(i, 1), 1);
    160         
    161         for (int j = 1; j <= f; ++j)
    162             add(food(nextInt()), cow(i, 0), 1);
    163         
    164         for (int j = 1; j <= d; ++j)
    165             add(cow(i, 1), drink(nextInt()), 1);
    166     }
    167     
    168     printf("%d
    ", maxFlow());
    169 }

    @Author: YouSiki

  • 相关阅读:
    ios--->cell里面 self 和self.contentview的区别
    ios--->tableView的估算高度的作用
    ios--->泛型
    ios--->上下拉刷新控件MJRefresh
    ios--->NSNotificationCenter传值
    ios--->ios消息机制(NSNotification 和 NSNotificationCenter)
    ios--->self.view.window在逻辑判断中的作用
    ios--->ios == 和 isEqual的用法区别
    序号 斑马线显示表格的代码
    vim 显示行号
  • 原文地址:https://www.cnblogs.com/yousiki/p/6253760.html
Copyright © 2011-2022 走看看