POJ 3281 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).

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

Hint

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.

 

还是一次做网络流

最大流模板题

建图时   注意拆点   注意边不要建多了

建个图 Dinic模板一套就好了

#include<queue>
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
const int  inf=1e9+7;
const int maxn=2e4+10;
const int maxm=5e4+10;
struct Edge
{
    int v,f,nxt;
};
int n,src,sink;
int g[maxn+10];
int nume;
Edge e[maxm*2+10];
void addedge(int u,int v,int c)
{
    e[++nume].v=v;
    e[nume].f=c;
    e[nume].nxt=g[u];
    g[u]=nume;
    e[++nume].v=u;
    e[nume].f=0;
    e[nume].nxt=g[v];
    g[v]=nume;
}

queue<int>que;
bool vis[maxn+10];
int dist[maxn+10];
int N,F,D;
void bfs()
{
    memset(dist,0,sizeof(dist));
    while(!que.empty())que.pop();
    vis[src]=true;
    que.push(src);
    while(!que.empty())
    {
        int u=que.front();
        que.pop();
        for(int i=g[u]; i; i=e[i].nxt)
        {
            if(e[i].f&&!vis[e[i].v])
            {
                que.push(e[i].v);
                dist[e[i].v]=dist[u]+1;
                vis[e[i].v]=true;
            }
        }
    }
}
int dfs(int u,int delta)
{
    if(u==sink)
        return delta;
    else
    {
        int ret=0;
        for(int i=g[u]; delta&&i; i=e[i].nxt)
        {
            if(e[i].f&&dist[e[i].v]==dist[u]+1)
            {
                int dd=dfs(e[i].v,min(e[i].f,delta));
                e[i].f-=dd;
                e[i^1].f+=dd;
                delta-=dd;
                ret+=dd;
            }
        }
        return ret;
    }
}
int maxflow()
{
    int ret=0;
    while(1)
    {
        memset(vis,0,sizeof(vis));
        bfs();
        if(!vis[sink])return ret;
        ret+=dfs(src,inf);
    }
}
void init()
{
    memset(g,0,sizeof(g));
    nume=1;
    scanf("%d%d%d",&N,&F,&D);
    src=N*2+F+D+1;
    sink=N*2+F+D+2;
    int x;
    for(int i=1; i<=F; i++)
    {
        x=i+2*N;
        addedge(src,x,1);
    }
    for(int i=1;i<=D;i++)
    {
        x=i+N*2+F;
        addedge(x,sink,1);
    }
    for(int i=1; i<=N; i++)
    {
        int d,f;
        scanf("%d%d",&f,&d);
        while(f--)
        {
            scanf("%d",&x);
            x=x+2*N;
            //addedge(x,src,1);
            //addedge(i,x,1);
            addedge(x,i,1);
        }
        while(d--)
        {
            scanf("%d",&x);
            x=x+N*2+F;
            //addedge(x,i+N,1);
            addedge(i+N,x,1);
            //addedge(x,sink,1);
            //addedge(sink,x,1);
        }
        addedge(i,i+N,1);
    }
    printf("%d\n",maxflow());
}
int main()
{
    init();
    return 0;
}

 

全部评论

相关推荐

不愿透露姓名的神秘牛友
06-21 11:33
昨天是学校最后一场招聘会,鼠鼠去参加了,全场只有一个招聘java的岗位,上来先做一份笔试题,做完后他拿张纸对答案,然后开始问简历上的问题,深圳小厂,6-8k(题目如下),后面还有两轮面试。然后我就在招聘现场逛呀逛,看到有公司招聘电商运营,给的比上年的小厂还多,鼠鼠就去了解了下,然后hr跟鼠鼠要了份简历,虽然我的简历上面全是求职Java开发相关的内容,但是hr还是鼓励我说没关系,她帮我把简历给老板看看,下周一会给我通知。招聘会结束后鼠鼠想了一段时间,也和朋友聊了聊,发现我可能是不太适合这个方向,然后就跟爸爸说回家了给我发条微信,我有些话想跟他说说。晚上爸爸到家了,跟我发了条微信,我立马跑出图书馆跟他打起了电话,这个通话长达一个小时,主要是跟爸爸坦白说我不想找这行了,是你的儿子太没用了,想试试其他行业。然后爸爸也跟我说了很多,说他从来没有希望我毕业后就赚大钱的想法,找不到就回家去,回家了再慢慢找,实在找不到就跟他干(帮别人装修房子,个体户),他也知道工作不好找,让我不要那么焦虑,然后就是聊一些家常琐事。对于后面的求职者呢我有点建议想提一下,就是如果招实习的时间或者秋招开始,而你的简历又很差的情况下,不要说等做好项目填充完简历之后再投,那样就太晚了,建议先把熟悉的项目写上简历,然后边投边面边完善,求职是一个人进步的过程,本来就比别人慢,等到一切都准备好后再投岂不是黄花菜都凉了。时间够的话还是建议敲一遍代码,因为那样能让你加深一下对项目的理解,上面那些说法只是针对时间不够的情况。当然,这些建议可能没啥用,因为我只是一个loser,这些全是建立在我理想的情况下,有没有用还需其他人现身说法。上篇帖子没想到学校被人认了出来,为了不丢脸只能匿名处理了。
KPLACE:找研发类或技术类,主要还是要1.多投 2.多做准备,很多方面都要做准备 3.要有心理准备,投累了就休息一两天,再继续,要相信自己能找到
投递58到家等公司7个岗位
点赞 评论 收藏
分享
07-11 13:16
湖南工学院 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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