POJ 3281 浅谈网络流基础建模

来源:互联网 发布:js 判断 运算符号 编辑:程序博客网 时间:2024/05/16 10:25

这里写图片描述
世界真的很大
这道题其实很水的
但是不知怎么的今天poj太卡了
等了好久结果才出来,还好一遍A了,不然不知道还要等多久
看题先:
description:

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

input

第一行输入三个整数N, F, D接下来n行,每行先输入两个整数 Fi 和 Di,分别表示编号为 i 的牛喜欢的食物和饮料的数量,接下来的Fi个整数表示第i头牛喜欢的食物的编号,最后Di个整数表示第i头牛喜欢的饮料的编号。

output

输出同时得到喜欢的食物和饮料的牛的数量的最大值。

题其实很简单的,但还是浅谈一下
题目给出了几种project之间的依赖关系,求最大匹配数
明确是最大流问题
每头牛有喜欢的饮料和食物,摆明了食物向牛建边,牛向饮料建边,边权为INF,因为不做限制条件
每种食物只有一个,源点向食物连边,边权为1,限制食物数目
每种饮料只有一个,饮料向汇点连边,边权为1,限制饮料数目
又因为每头牛只能吃一套饮料和食物,所以牛拆点建一条边权为1的边,以限制牛吃套餐的数量
不同物品间用数量区别开就好
完整代码:

#include<stdio.h>#include<queue>#include<cstring>#include<algorithm>using namespace std;const int INF=0x3f3f3f3f;struct edge{    int v,last,w;}ed[100010];queue <int> state;int head[100010],dis[100010];int ans=0,num=1,S,T,F,D,n;void add(int u,int v,int w){    num++;    ed[num].v=v;    ed[num].w=w;    ed[num].last=head[u];    head[u]=num;}bool bfs(){    while(state.size()) state.pop();    memset(dis,-1,sizeof(dis));    dis[S]=0;    state.push(S);    while(!state.empty())    {        int u=state.front();        state.pop();        for(int i=head[u];i;i=ed[i].last)        {            int v=ed[i].v;            if(dis[v]==-1&&ed[i].w>0)            {                dis[v]=dis[u]+1;                state.push(v);            }        }    }    if(dis[T]==-1) return 0;    return 1;}int dfs(int u,int low){    if(u==T || low==0) return low;    int a=0;    for(int i=head[u];i;i=ed[i].last)    {        int v=ed[i].v;        if(ed[i].w>0&&dis[v]==dis[u]+1)        {            int tmp=dfs(v,min(low,ed[i].w));            ed[i].w-=tmp;            ed[i^1].w+=tmp;            a+=tmp,low-=tmp;            if(low==0) return a;        }    }    if(low) dis[u]=-1;    return a;}int main(){    scanf("%d%d%d",&n,&F,&D);    S=0,T=F+n+n+D+1;    for(int i=1;i<=n;i++)    {        int a,b,x;        scanf("%d%d",&a,&b);        add(i+F,i+F+n,1);        add(i+F+n,i+F,0);        for(int j=1;j<=a;j++)        {            scanf("%d",&x);            add(x,i+F,INF);            add(i+F,x,0);        }        for(int j=1;j<=b;j++)        {            scanf("%d",&x);            add(i+F+n,x+F+n+n,INF);            add(x+F+n+n,i+F+n,0);        }    }    for(int i=1;i<=F;i++)    {        add(S,i,1);        add(i,S,0);    }    for(int i=1;i<=D;i++)    {        add(F+n+n+i,T,1);        add(T,F+n+n+i,0);    }    while(bfs())         ans+=dfs(S,INF);    printf("%d\n",ans);    return 0;}/*Whoso pulleth out this sword from this stone and anvil is duly born King of all England*/

嗯,就是这样

原创粉丝点击