Dining

来源:互联网 发布:黄鹤tv武汉网络电视 编辑:程序博客网 时间:2024/06/08 06:55

Description
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).

Input
Line 1: Three space-separated integers: N, F, and D
Lines 2.. N+1: Each line i starts with a two integers Fi and Di, the number of dishes that cow i likes and the number of drinks that cow i likes. The next Fi integers denote the dishes that cow i will eat, and the Di integers following that denote the drinks that cow i will drink.
Output
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
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
Sample Output
3
有n个牛,只喝特定的水,吃特定的饭,问最多满足多少头牛。
这是两个匹配,匹配水和匹配饭,一开始的想法是扫一遍牛,先判断能否满足水,再判断满足饭,如果都满足就加入。
然而是错的,因为这需要把两个匹配所有的可能都连接起来,然而并不能实现。

正确的建图并不能想到,将水变为f个点,与n个牛连接起来,再把牛与饭连接起来,再做一个起点和终点,起点连水,终点连饭,如果有起点到终点的通路,就说明从水到牛到饭是有匹配的,然而还要考虑到,每头牛只能使用一次,所以要把牛用两个点标记连接,这样就处理了牛的使用次数问题。

#include<cstdio>#include<cstring>#include<iostream>#include<queue>#include<vector>#include<algorithm>#include<string>#include<cmath>#include<set>#include<map>using namespace std;typedef long long ll;const int inf = 0x3f3f3f3f;const int maxn = 1005;struct Edge{    int form, to, cap, flow;    Edge(int u, int v, int c, int f) :form(u), to(v), cap(c), flow(f){}};struct EdmondKarp{    int n, m;    vector<Edge>edges;    vector<int>G[maxn];    int a[maxn];    int p[maxn];    void init(int n)    {        for (int i = 0; i < n; i++)G[i].clear();        edges.clear();    }    void AddEdge(int from, int to, int cap)    {        edges.push_back(Edge(from, to, cap, 0));        edges.push_back(Edge(to, from, 0, 0));        m = edges.size();        G[from].push_back(m - 2);        G[to].push_back(m - 1);    }    int Maxflow(int s, int t)    {        int flow = 0;        for (;;)        {            memset(a, 0, sizeof(a));            queue < int >Q;            Q.push(s);            a[s] = inf;            while (Q.size())            {                int x = Q.front(); Q.pop();                for (int i = 0; i < G[x].size(); i++)                {                    Edge& e = edges[G[x][i]];                    if (!a[e.to] && e.cap>e.flow)                    {                        p[e.to] = G[x][i];                        a[e.to] = min(a[x], e.cap - e.flow);                        Q.push(e.to);                    }                }                if (a[t])break;            }            if (!a[t])break;            for (int u = t; u != s; u = edges[p[u]].form)            {                edges[p[u]].flow += a[t];                edges[p[u] ^ 1].flow -= a[t];            }            flow++;        }        return flow;    }}ans;int main(){    int i, j, m, n, t, f, d, s;    while (scanf("%d%d%d", &n, &f, &d) != EOF)    {        ans.init(305);        s = 0; t = n + f + d + 1 + n;        for (i = 1; i <= f; i++)            ans.AddEdge(0, i, 1);        for (i = 1; i <= n; i++)        {            int x, y, temp;            cin >> x >> y;            for (j = 1; j <= x; j++)            {                cin >> temp;                ans.AddEdge(temp, f + i, 1);            }            for (j = 1; j <= y; j++)            {                cin >> temp;                ans.AddEdge(f + n + i, temp + n * 2 + f, 1);            }        }        for (i = 1; i <= n; i++)            ans.AddEdge(f + i, f + n + i, 1);        for (i = 1; i <= d; i++)            ans.AddEdge(n + n + f + i, t, 1);        cout << ans.Maxflow(0, t) << endl;    }    return 0;}
0 0
原创粉丝点击