• [USACO07OPEN]吃饭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).

    有F种食物和D种饮料,每种食物或饮料只能供一头牛享用,且每头牛只享用一种食物和一种饮料。现在有n头牛,每头牛都有自己喜欢的食物种类列表和饮料种类列表,问最多能使几头牛同时享用到自己喜欢的食物和饮料。(1 <= f <= 100, 1 <= d <= 100, 1 <= n <= 100)

    输入输出格式

    输入格式:

    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.

    输出格式:

    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

    输入输出样例

    输入样例#1:

    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:

    3
    

    Solution

    这题算是一个比较裸的网络流了,看上去可以发现我们要限制每个牛配一个吃的和一个喝的。嗯,那么比较容易有的思路就是一个连到牛上,一个从牛上连出去,就可以保证这一点。但是光这样还不够,一个牛会把所有能吃能喝的全选走。那么把牛拆成两个牛,然后之间连1的边即可。

    Code

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #define re register
    #define inf 400000000
    #define MAXN 10001
    #define MAXM 100001
    using namespace std;
    int n,s,q,dis[2000011],t,l,cur[200051];
    struct po
    {
        int nxt,to,w;
    }edge[MAXM];
    int head[MAXN],dep[MAXN],num=-1;
    inline int read()
    {
        int x=0,c=1;
        char ch=' ';
        while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
        while(ch=='-')c*=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();
        return x*c;
    }
    inline void add_edge(int from,int to,int w)
    {
        edge[++num].nxt=head[from];
        edge[num].to=to;
        edge[num].w=w;
        head[from]=num;
    }
    inline void add(int from,int to,int w)
    {
        add_edge(from,to,w);
        add_edge(to,from,0);
    }
    inline bool bfs()
    {
        memset(dep,0,sizeof(dep));
        queue<int> q;
        while(!q.empty())
        q.pop();
        q.push(s);
        dep[s]=1;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(re int i=head[u];i!=-1;i=edge[i].nxt)
            {
                int v=edge[i].to;
                if(dep[v]==0&&edge[i].w>0)
                {
                    dep[v]=dep[u]+1;
                    if(v==t)
                    return 1;
                    q.push(v);
                }
            }
        }
        return 0;
    }
    inline int dfs(int u,int dis)
    {
        if(u==t)
        return dis;
        int diss=0;
        for(re int& i=cur[u];i!=-1;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(edge[i].w!=0&&dep[v]==dep[u]+1)
            {
                int check=dfs(v,min(dis,edge[i].w));
                if(check>0)
                {
                    dis-=check;
                    diss+=check;
                    edge[i].w-=check;
                    edge[i^1].w+=check;
                    if(dis==0) break;
                }
            }
        }
        return diss;
    }
    inline int dinic()
    {
        int ans=0;
        while(bfs())
        {
            for(re int i=0;i<=t;i++)
            cur[i]=head[i];
            while(int d=dfs(s,inf))
            ans+=d;
        }
        return ans;
    }
    int main() 
    {
        //freopen("date.in","r",stdin);
        memset(head,-1,sizeof(head));
        n=read();
        int F=read(),D=read();
        s=0;t=n+n+F+D+1;
        for(re int i=1;i<=n;i++){
            int f=read(),d=read();
            int x;
            for(re int j=1;j<=f;j++)
                x=read(),add(x,F+i,1);
            add(F+i,F+n+i,1);
            for(re int j=1;j<=d;j++)
                x=read(),add(F+n+i,F+n+n+x,1);
        }
        for(re int i=1;i<=F;i++)
            add(s,i,1);
        for(re int i=1;i<=D;i++)
            add(n+n+F+i,t,1);
       
        cout<<dinic();
        return 0;
    }
    
  • 相关阅读:
    主机连接虚拟机redis 服务器
    在dockers中调试dump的dotnet程序
    我的devops实践经验分享一二
    【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--请求处理结果适配篇(7/8)
    【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--参数自动映射篇(6/8)
    【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--请求处理函数装饰器注册篇(5/8)【controller+action】
    【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--控制器和处理函数的注册篇(4/8)【controller+action】
    【nodejs】让nodejs像后端mvc框架(asp.net mvc )一样处理请求--控制器的声明定义和发现篇(3/8)
    【nodejs】让nodejs像后端mvc框架(asp.net mvc )一样处理请求--路由限制及选择篇(2/8)【route】
    【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--目录(8/8 完结)
  • 原文地址:https://www.cnblogs.com/victorique/p/8964055.html
Copyright © 2020-2023  润新知