zoukankan      html  css  js  c++  java
  • [BZOJ1711][Usaco2007 Open]Dining吃饭

    1711: [Usaco2007 Open]Dining吃饭

    Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 1057  Solved: 569 [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总食品和饮料).当然,别的数据会更难.
     
    最大流(传说中的三分匹配??)
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    struct Edge{
        int to, cap, next;
        Edge(){}
        Edge(int _t, int _w, int _n): to(_t), cap(_w), next(_n){}
    }e[50000];
    int fir[410] = {0}, cur[410], cnt = 1;
    inline void ins(int u, int v, int w){
        e[++cnt] = Edge(v, w, fir[u]); fir[u] = cnt;
        e[++cnt] = Edge(u, 0, fir[v]); fir[v] = cnt;
    }
    int sour, sink;
    int lev[410], vis[410], bfn = 0;
    int q[410], h, t;
    inline bool bfs(){
        h = t = 0;
        q[t++] = sour;
        vis[sour] = ++bfn;
        lev[sour] = 1;
        while(h != t){
            for(int i = fir[q[h]]; i; i = e[i].next){
                if(!e[i].cap || vis[e[i].to] == bfn) continue;
                vis[e[i].to] = bfn;
                lev[e[i].to] = lev[q[h]] + 1;
                q[t++] = e[i].to;
            }
            h++;
        }
        return vis[sink] == bfn;
    }
    int dfs(int now, int flow){
        if(now == sink) return flow;
        int t, ret = 0;
        for(int &i = cur[now]; i; i = e[i].next){
            if(!e[i].cap || lev[e[i].to] != lev[now] + 1) continue;
            t = dfs(e[i].to, min(flow, e[i].cap));
            ret += t;
            flow -= t;
            e[i].cap -= t;
            e[i ^ 1].cap += t;
            if(!flow) break;
        }
        if(!ret) lev[now] = 0;
        return ret;
    }
    int N, F, D;
    int main(){
        scanf("%d %d %d", &N, &F, &D);
        sour = 0;
        sink = N * 2 + F + D + 1;
        for(int i = 1; i <= N; i++) ins(i, i + N, 1);
        for(int i = 1; i <= F; i++) ins(sour, i + 2 * N, 1);
        for(int i = 1; i <= D; i++) ins(i + F + 2 * N, sink, 1);
        for(int f, d, t, i = 1; i <= N; i++){
            scanf("%d %d", &f, &d);
            for(int j = 1; j <= f; j++){
                scanf("%d", &t);
                ins(t + 2 * N, i, 1);
            }
            for(int j = 1; j <= d; j++){
                scanf("%d", &t);
                ins(i + N, t + 2 * N + F, 1);
            }
        }
        int ans = 0;
        while(bfs()){
            for(int i = sour; i <= sink; i++) cur[i] = fir[i];
            ans += dfs(sour, 1 << 30);
        }
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    HTTPS安全超文本传输协议
    前端性能监控工具
    跨域:跨域及解决方法
    源码安装nginx
    浏览器工作原理(四):浏览器事件解读
    浏览器工作原理(三):js运行机制及Event Loop
    前端性能优化:gzip压缩文件传输数据
    Vue源码学习(零):内部原理解析
    netsh命令操作ipsec
    netsh命令操作防火墙
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7491735.html
Copyright © 2011-2022 走看看