WOJ1223-Dining

Cows are such finicky eaters. Each cow has a preference for certain
foods and drinks, and she will consume no others.

Farmer John has cooked fabulous meals for his cows, but he forgot
to check his menu against their preferences. Although he might not
be able to stuff everybody, he wants to give a complete meal of
both food and drink to as many cows as possible.

Farmer John has cooked F (1 <= F <= 100) types of foods and prepared
D (1 <= D <= 100) types of drinks. Each of his N (1 <= N <= 100)
cows has decided whether she is willing to eat a particular food
or drink a particular drink. Farmer John must assign a food type
and a drink type to each cow to maximize the number of cows who get
both.

Each dish or drink can only be consumed by one cow (i.e., once food
type 2 is assigned to a cow, no other cow can be assigned food type
2).

输入格式

  • Line 1: Three space-separated integers: N, F, and D

  • Lines 2..N+1: Each line i starts with a two integers F_i and D_i, the number of dishes that cow i likes and the number of drinks that cow i likes. The next F_i integers denote the dishes that cow i will eat, and the D_i integers following that denote the drinks that cow i will drink.

输出格式

  • Line 1: A single integer that is the maximum number of cows that can be fed both food and drink that conform to their wishes

样例输入

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

样例输出

3

提示

INPUT DETAILS:

Cow 1: foods from {1,2}, drinks from {1,3}
Cow 2: foods from {2,3}, drinks from {1,2}
Cow 3: foods from {1,3}, drinks from {1,2}
Cow 4: foods from {1,3}, drinks from {3}

OUTPUT DETAILS:

One way to satisfy three cows is:
Cow 1: no meal
Cow 2: Food #2, Drink #2
Cow 3: Food #1, Drink #1
Cow 4: Food #3, Drink #3
The pigeon-hole principle tells us we can do no better since there are only
three kinds of food or drink. Other test data sets are more challenging, of
course.


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<map>
using std::min;
using std::sort;
using std::pair;
using std::swap;
using std::queue;
using std::vector;
using std::multimap;
#define pb(e) push_back(e)
#define sz(c) (int)(c).size()
#define mp(a, b) make_pair(a, b)
#define all(c) (c).begin(), (c).end()
#define iter(c) __typeof((c).begin())
#define cls(arr, val) memset(arr, val, sizeof(arr))
#define cpresent(c, e) (find(all(c), (e)) != (c).end())
#define rep(i, n) for(int i = 1; i <= (int)n; i++)
#define tr(c, i) for(iter(c) i = (c).begin(); i != (c).end(); ++i)
const int Max_N = 1100;
const int INF = 0x3f3f3f3f;
struct Ford_Fulkerson {
    struct edge { int to, cap, next, rev; }G[Max_N << 2];
    int  N, F, D, tot, head[Max_N];
    bool vis[Max_N], Food[Max_N][Max_N], Drink[Max_N][Max_N];
    inline void init(int n, int f, int d) {
        tot = 0;
        this->N = n, this->F = f, this->D =d;
        cls(head, -1), cls(Food, false), cls(Drink, false);
    }
    inline void add_edge(int u, int v, int cap = 1) {
        G[tot] = (edge){ v, cap, head[u], tot + 1 }; head[u] = tot++;
        G[tot] = (edge){ u,   0, head[v], tot - 1 }; head[v] = tot++;
    }
    inline void built() {
        int x, y, v;
        rep(i, N) {
            scanf("%d %d", &x, &y);
            while(x--) {
                scanf("%d", &v);
                Food[i][v] = true;
            }
            while(y--) {
                scanf("%d", &v);
                Drink[i][v] = true;
            }
        }
    }
    inline int dfs(int u, int t, int f) {
        if(u == t) return f;
        vis[u] = true;
        for(int i = head[u]; ~i; i = G[i].next) {
            edge &e = G[i];
            if(e.cap > 0 && !vis[e.to]) {
                int d = dfs(e.to, t, min(e.cap, f));
                if(d > 0) {
                    e.cap -= d;
                    G[e.rev].cap +=d;
                    return d;
                }
            }
        }
        return 0;
    }
    inline void max_flow(int s, int t) {
        int flow = 0;
        while(true) {
            cls(vis, false);
            int f = dfs(s, t, INF);
            if(!f) break;
            flow += f;
        }
        printf("%d\n", flow);
    }
    inline void solve() {
        int s = 1, t = s + F + 2 * N + D + 1;
        rep(i, F) {
            add_edge(s, s + i);
        }
        rep(i, D) {
            add_edge(s + F + 2 * N + i, t);
        }
        rep(i, N) {
            add_edge(s + F + i, s + F + N + i, 1);
            rep(j, F) {
                if(Food[i][j]) add_edge(s + j, s + F + i);
            }
            rep(j, D) {
                if(Drink[i][j]) add_edge(s + F + N + i, s + F + 2 * N + j);
            }
        }
        max_flow(s, t);
    }
}go;
int main() {
    int n, f, d;
    while(~scanf("%d %d %d", &n, &f, &d)) {
        go.init(n ,f ,d);
        go.built();
        go.solve();
    }
    return 0;
}


全部评论

相关推荐

07-07 14:30
复旦大学 Java
遇到这种人我也不知道说啥了
无能的丈夫:但我觉得这个hr语气没什么问题啊(没有恶意
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-07 12:04
毕业生招你惹你了,问一个发薪日来一句别看网上乱七八糟的你看哪个工作没有固定发薪日扭头就取消了面试就问了一句公司都是这个态度吗还搞上人身攻击了...
程序员小白条:呃呃呃,都还没面试,我都不会问这么细,何况通不通过,去不去都另说,你没实力和学历的话,在外面就这样,说实话没直接已读不回就不错了,浪费时间基本上
点赞 评论 收藏
分享
屌丝逆袭咸鱼计划:心态摆好,man,晚点找早点找到最后都是为了提升自己好进正职,努力提升自己才是最关键的😤难道说现在找不到找的太晚了就炸了可以鸡鸡了吗😤早实习晚实习不都是为了以后多积累,大四学长有的秋招进的也不妨碍有的春招进,人生就这样
点赞 评论 收藏
分享
人力小鱼姐:实习经历没有什么含金量,咖啡店员迎宾这种就别写了,其他两段包装一下 想找人力相关的话,总结一下个人优势,结合校园经历里有相关性的部分,加一段自我评价
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务