zoukankan      html  css  js  c++  java
  • P2891 [USACO07OPEN]吃饭Dining

    题目描述

    有F种食物和D种饮料,每种食物或饮料只能供一头牛享用,且每头牛只享用一种食物和一种饮料。现在有n头牛,每头牛都有自己喜欢的食物种类列表和饮料种类列表,问最多能使几头牛同时享用到自己喜欢的食物和饮料。
    输入输出格式

    第1行输入三个数n,F,D(1 <= F <= 100, 1 <= D <= 100, 1 <= n <= 100)
    第n+1行输入fi,di(0<= fi<= F, 1 <= d i<= D)接下来di个数输入牛喜欢的饮料
    fi个数输入牛喜欢的食物
    思路
    我们很容易想到先用每个食物连牛,牛再连饮料,但这样是错的,很简单的例子在这里插入图片描述
    怎么解决恁,我们可以把牛拆点,拆成连个点限制流量
    这样S (->) 食物 (->)(->)(->) 饮料 (->) T就好了
    在这里插入图片描述
    代码

    #include<bits/stdc++.h>
    #define inf 1<<30
    using namespace std;
    const int maxn=400+10,maxm=200000+100;
    int size=1;
    int head[maxn];
    bool vis[maxn];
    int s,t;
    struct edge
    {
        int to,next,cap;
    }e[maxm];
    inline void addedge(int u,int v,int val)
    {
        e[++size].to=v;e[size].cap=val;e[size].next=head[u];head[u]=size;
        e[++size].to=u;e[size].cap=0;e[size].next=head[v];head[v]=size;
    }
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
        while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f; 
    }
    int dfs(int u,int f)
    {
        if(u==t)
        return f; 
        vis[u]=1;
        for(int i=head[u];i;i=e[i].next)
        {
            int to=e[i].to;
            if(!vis[to]&&e[i].cap>0)
            {
                int d=dfs(to,min(f,e[i].cap));
                if(d>0)
                {
                    e[i].cap-=d;
                    e[i^1].cap+=d;
                    return d;
                }
            }
        }
        return 0;
    }
    int maxflow()
    {
        int flow=0;
        while(1)
        {
            memset(vis,0,sizeof(vis));
            int f=dfs(s,inf);
            if(f==0)return flow;
            flow+=f;
        }
    }
    int main()
    {
        int n=read(),f=read(),d=read();
        s=0,t=2*n+f+d+1;
        for(int i=1;i<=n;i++)
        addedge(f+i,f+i+n,1); 
        for(int i=1;i<=f;i++)
        addedge(s,i,1);
        for(int i=1;i<=d;i++)
        addedge(f+2*n+i,t,1); 
        for(int i=1;i<=n;i++)
        {
            int a=read(),b=read();
            for(int j=1;j<=a;j++)
            {
            	int x=read();
            	addedge(x,f+i,1);
            }
            for(int j=1;j<=b;j++)
            {
                int x=read();
                addedge(f+n+i,f+2*n+x,1);
            } 
        }
        printf("%d",maxflow()); 
        return 0;
    } 
    
  • 相关阅读:
    关于程序中以时间判断接收数据结束时,接收数据长度设置为1时,出现接收不全的问题解释。
    stm32 外部8M晶振 改为12M的方法
    django iis 部署
    电信NB卡
    socketserver
    APScheduler简介
    三极管开关电路
    mysql授权
    解决VMware无法共享ubuntu虚拟机文件
    Python解析yaml配置文件
  • 原文地址:https://www.cnblogs.com/DriverBen/p/10542933.html
Copyright © 2011-2022 走看看