POJ 3281 Dining

对顶楼表示膜拜


老实说,要到几岁才开始不相信圣诞老人的存在……这类无聊的话题对我而言,根本不痛不痒的。不过,讲到我从几岁起开始不相信圣诞老人就是那个穿着红衣服的老公公时,我能确定地说,我根本打从一开始就不相信。

    我知道幼稚园圣诞节庆祝会时出现的圣诞老人是假的,回溯记忆,还能记起周围的幼稚园小朋友都一脸不信任地望着假扮圣诞老人的园长老师。

    即使没有撞见老妈正在亲吻圣诞老公公,机灵的我也老早就怀疑只在圣诞节工作的老爷爷是否真的存在了。不过,我却是过了很久以后,才发现外星人、幽灵、妖怪、超能力者以及特摄、动画里头,那些与邪恶组织战斗的英雄们并不存在这世上。

    不,说不定我早就发现了,只不过一直不想承认而已。因为,在我的内心深处,是十分渴望那些外星人、幽灵、妖怪、超能力者以及邪恶组织突然出现在眼前的。

    和我生活的这个普通世界相比,特摄、动画里头所描绘的世界,反而更有魅力。

    我也想活在那种世界里!

    我真的好想拯救被外星人绑架并关在透明的大型豌豆夹里头的少女…也想拿着雷射枪运用智慧与勇气击退企图改写历史的未来人…或者光用一句咒语就收拾了恶灵跟妖怪,再不然就是和秘密组织的超能力者进行超能力的战斗!

    等等,冷静一下,假设我被外星人等等(以下略)那类的生物袭击,没有任何特殊能力的我怎么可能和他们对抗?于是,我便如是幻想——

    某天,班上突然转来一个谜样的转学生,他其实是个外星人或未来人那类的生物,并拥有未知的能力,后来他跟坏人战斗,而我只要设法让自己被卷进那场战争就好了。主要战斗的人是他,而我则是追随他的小跟班。啊啊,实在太棒了,我真是聪明啊!

    要不然就是这样。某天,我那不可思议的力量突然觉醒,就像隔空取物或精神念力之类的。而且地球上其实还有很多拥有超能力的人类存在,自然也会有一个组织专门收容这些人。

    不久之后,善良的组织便派人来迎接我。而我也成为组织的一员共同对抗企图征服世界的邪恶超能力者。

    不过,现实却是意外地残酷。

    ......

农夫为他的 N (1 ≤ N ≤ 100) 牛准备了 F (1 ≤ F ≤ 100)种食物和 D (1 ≤ D ≤ 100) 种饮料。每头牛都有各自喜欢的食物和饮料,而每种食物或饮料只能分配给一头牛。最多能有多少头牛可以同时得到喜欢的食物和饮料?

Input

第一行输入三个整数N, F, D

接下来n行,每行先输入两个整数 Fi 和 Di,分别表示编号为 i 的牛喜欢的食物和饮料的数量,接下来的Fi个整数表示第i头牛喜欢的食物的编号,最后Di个整数表示第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

Sample Output

3

第一次用ek超时了这么佛系么,再来几次....过了emmmm

这道题我先开始一直在纠结怎么才能让源点->牛->食物->饮料->终点建立联系可是好像不行,然后看了题解=.=,可以把牛放在中间  源点->食物->牛->牛->饮料->终点   这样把源点和食物连一下,牛和牛连一下 ,饮料和终点连一下  剩下的就ok了

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<string.h>
#define maxn  405
#define inf 0x3f3f3f3f
using namespace std;
int star,last;
queue<int>que;
int gra[maxn][maxn],path[maxn],flow[maxn];
int bfs()
{
    int t;
    while(!que.empty())que.pop();
    memset(path,-1,sizeof(path));
    path[star]=0,flow[star]=inf;
    que.push(star);
    while(!que.empty())
    {
        t=que.front();
        que.pop();
        if(t==last) break;
        for(int i=1;i<=last;i++)
        {
            if(i!=star && path[i]==-1 && gra[t][i])
            {
                flow[i]=flow[t]<gra[t][i]?flow[t]:gra[t][i];
                que.push(i);
                path[i]=t;
            }
        }
    }
    if(path[last]==-1)return -1;
    return flow[last];
}
int Edmods_Karp()
{
    int max_flow=0,step,now,pre;
    while((step=bfs())!=-1)
    {
        now=last;
        while(now!=star)
        {
            pre=path[now];
            gra[pre][now]-=step;
            gra[now][pre]+=step;
            now=pre;
        }
        max_flow+=step;
    }
    return max_flow;
}
int main()
{
    int n,f,d,lf,lw;
    while(scanf("%d%d%d",&n,&f,&d)==3)
    {
    memset(gra,0,sizeof(gra));
    memset(flow,0,sizeof(flow));
    star=0,last=2*n+f+d+1;
    for(int i=1;i<=f;i++) gra[0][i]=1;
    for(int i=1;i<=d;i++) gra[2*n+f+i][last]=1;
    for(int i=1;i<=n;i++) gra[f+i][f+n+i]=1;
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&lf,&lw);
        for(int j=1;j<=lf;j++)
        {
            int temp;
            scanf("%d",&temp);
            gra[temp][f+i]=1;
        }
        for(int j=1;j<=lw;j++)
        {
            int temp;
            scanf("%d",&temp);
            gra[i+f+n][2*n+f+temp]=1;
        }
    }
    printf("%d\n",Edmods_Karp());
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值