Dining
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 11844   Accepted: 5444

Description

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.
题解:一共n头母牛,想要吃的和喝的,每头母牛有一样吃的有一样喝的就满足了,现在有F种吃的,D种喝的,吃的和喝的只能被用一次,求可以满足的母牛个数;
这个题可以加一个源点,一个终点,将吃的左边与源点连,右边与母牛连,将母牛拆点,母牛右边与喝的连,喝的与终点连。。。
代码:
 #include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#define mem(x,y) memset(x,y,sizeof(x))
using namespace std;
const int INF=0x3f3f3f3f;
const int MAXN=;
const int MAXM=<<;
int head[MAXM];
int vis[MAXN],dis[MAXN];
int edgnum;
struct Node{
int from,to,next,cup,flow;
};
Node edg[MAXM];
queue<int>dl;
void add(int u,int v,int w){
Node E={u,v,head[u],w,};
edg[edgnum]=E;
head[u]=edgnum++;
E={v,u,head[v],,};
edg[edgnum]=E;
head[v]=edgnum++;
}
void initial(){
mem(head,-);edgnum=;
}
bool bfs(int s,int e){
mem(vis,);mem(dis,-);
while(!dl.empty())dl.pop();
dis[s]=;vis[s]=;dl.push(s);
while(!dl.empty()){
int u=dl.front();
dl.pop();
for(int i=head[u];i!=-;i=edg[i].next){
Node v=edg[i];
if(!vis[v.to]&&v.cup>v.flow){
vis[v.to]=;dl.push(v.to);
dis[v.to]=dis[u]+;
if(v.to==e)return true;
}
}
}
return false;
}
int dfs(int x,int la,int e){
if(x==e||la==)return la;
int temp;
int flow=;
for(int i=head[x];i!=-;i=edg[i].next){
Node &v=edg[i];
if(dis[v.to]==dis[x]+&&(temp=dfs(v.to,min(la,v.cup-v.flow),e))>){
v.flow+=temp;
edg[i^].flow-=temp;
la-=temp;
flow+=temp;
if(la==)break;
}
}
return flow;
}
int maxflow(int s,int e){
int flow=;
while(bfs(s,e)){
flow+=dfs(s,INF,e);
}
return flow;
}
int main(){
int n,F,D,f,d,a,b;
while(~scanf("%d%d%d",&n,&F,&D)){
initial();
for(int i=;i<=n;i++){
scanf("%d%d",&f,&d);
while(f--){
scanf("%d",&a);
add(*n+a,i,);
}
while(d--){
scanf("%d",&a);
add(n+i,*n+F+a,);
}
add(i,n+i,);
}
for(int i=;i<=F;i++)add(,*n+i,);
for(int i=;i<=D;i++)add(*n+F+i,*n+F+D+,);
printf("%d\n",maxflow(,*n+F+D+));//醉了,应该从0开始,找了半天错。。。
}
return ;
}

另一种解法:

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#define mem(x,y) memset(x,y,sizeof(x))
using namespace std;
const int INF=0x3f3f3f3f;
const int MAXN=;
const int MAXM=<<;
queue<int>dl;
int vis[MAXN],map[MAXN][MAXN],pre[MAXN];
bool bfs(int s,int e){
mem(vis,);mem(pre,-);
while(!dl.empty())dl.pop(); //忘了初始化。。。。。
vis[s]=;dl.push(s);
int a;
while(!dl.empty()){
a=dl.front();
dl.pop();//忘写pop了。。。
if(a==e)return true;
for(int i=;i<=e;i++){
if(!vis[i]&&map[a][i]){
dl.push(i);
vis[i]=;
pre[i]=a;
//if(i==e)return true;
}
}
}
return false;
}
int maxflow(int s,int e){
int flow=;
while(bfs(s,e)){
int temp=INF;
int r=e;
//puts("fasf");
while(r!=s)temp=min(temp,map[pre[r]][r]),r=pre[r];
r=e;
while(r!=s)map[pre[r]][r]-=temp,map[r][pre[r]]+=temp,r=pre[r];
flow+=temp;
}
return flow;
}
int main(){
int n,F,D,f,d,a,b;
while(~scanf("%d%d%d",&n,&F,&D)){
mem(map,);
for(int i=;i<=n;i++){
scanf("%d%d",&f,&d);
while(f--){
scanf("%d",&a);
// add(2*n+a,i,1);
map[*n+a][i]=;
}
while(d--){
scanf("%d",&a);
// add(n+i,2*n+F+a,1);
map[n+i][*n+F+a]=;
}
//add(i,n+i,1);
map[i][n+i]=;
}
for(int i=;i<=F;i++)map[][*n+i]=;//add(0,2*n+i,1);
for(int i=;i<=D;i++)map[*n+F+i][*n+F+D+]=;//add(2*n+F+i,2*n+F+D+1,1);
printf("%d\n",maxflow(,*n+F+D+));//醉了,应该从0开始,找了半天错。。。
}
return ;
}

Dining(最大流)的更多相关文章

  1. POJ3281 Dining —— 最大流 + 拆点

    题目链接:https://vjudge.net/problem/POJ-3281 Dining Time Limit: 2000MS   Memory Limit: 65536K Total Subm ...

  2. POJ 3281 Dining(最大流)

    POJ 3281 Dining id=3281" target="_blank" style="">题目链接 题意:n个牛.每一个牛有一些喜欢的 ...

  3. POJ3281 Dining 最大流

    题意:有f种菜,d种饮品,每个牛有喜欢的一些菜和饮品,每种菜只能被选一次,饮品一样,问最多能使多少头牛享受自己喜欢的饮品和菜 分析:建边的时候,把牛拆成两个点,出和入 1,源点向每种菜流量为1 2,每 ...

  4. 【网络流#7】POJ 3281 Dining 最大流 - 《挑战程序设计竞赛》例题

    不使用二分图匹配,使用最大流即可,设源点S与汇点T,S->食物->牛->牛->饮料->T,每条边流量为1,因为流过牛的最大流量是1,所以将牛拆成两个点. 前向星,Dini ...

  5. P2891 [USACO07OPEN]吃饭Dining 最大流

    \(\color{#0066ff}{ 题目描述 }\) 有F种食物和D种饮料,每种食物或饮料只能供一头牛享用,且每头牛只享用一种食物和一种饮料.现在有n头牛,每头牛都有自己喜欢的食物种类列表和饮料种类 ...

  6. [poj3281]Dining(最大流+拆点)

    题目大意:有$n$头牛,$f$种食物和$d$种饮料,每种食物或饮料只能供一头牛享用,且每头牛只享用一种食物和一种饮料.每头牛都有自己喜欢的食物种类列表和饮料种类列表,问最多能使几头牛同时享用到自己喜欢 ...

  7. poj3281 Dining 最大流(奇妙的构图)

    我是按照图论500题的文档来刷题的,看了这题怎么也不觉得这是最大流的题目.这应该是题目做得太少的缘故. 什么是最大流问题?最大流有什么特点? 最大流的特点我觉得有一下几点: 1.只有一个起点.一个终点 ...

  8. POJ 3281 Dining(最大流板子)

    牛是很挑食的.每头牛都偏爱特定的食物和饮料,其他的就不吃了. 农夫约翰为他的牛做了美味的饭菜,但他忘了根据它们的喜好检查菜单.虽然他不可能喂饱所有的人,但他想让尽可能多的奶牛吃上一顿有食物和水的大餐. ...

  9. POJ 3281 Dining 最大流

    饮料->牛->食物. 牛拆成两点. //#pragma comment(linker, "/STACK:1024000000,1024000000") #include ...

  10. POJ 3281 Dining(最大流+拆点)

    题目链接:http://poj.org/problem?id=3281 题目大意:农夫为他的 N (1 ≤ N ≤ 100) 牛准备了 F (1 ≤ F ≤ 100)种食物和 D (1 ≤ D ≤ 1 ...

随机推荐

  1. 最大值减去最小值小于或等于num的子数组数量

    [说明]: 本文是左程云老师所著的<程序员面试代码指南>第一章中“最大值减去最小值小于或等于num的子数组数量”这一题目的C++复现. 本文只包含问题描述.C++代码的实现以及简单的思路, ...

  2. selenium + python自动化测试环境搭建--亲测

    环境准备: 1.下载所学安装包: setuptools https://pypi.python.org/packages/2.7/s/setuptools/ selenium https://pypi ...

  3. 通过读取excel数据和mysql数据库数据做对比(二)-代码编写测试

    通过上一步,环境已搭建好了. 下面开始实战, 首先,编写链接mysql的函数conn_sql.py import pymysql def sql_conn(u,pwd,h,db): conn=pymy ...

  4. Nexus 5 电信破解问题 CDMA_HDR重启会变回LTE

    解决方法是Nexus 5 Field Test Mode -Advanced LTE Settings 关掉LTE 重启就好了 在Android 5.0 下实测成功 如果不行就换一张卡 重新写 重启再 ...

  5. kinect for windows - DepthBasics-D2D详解之三

    这篇文章我们将总结一下,之前两篇文章中提到的Kinect SDK的函数接. 函数接口: NuiGetSensorCount: 获取连接的Kinect设备个数 原型:_Check_return_ HRE ...

  6. Windows Azure 社区新闻综述(#74 版)

    欢迎查看最新版本的每周综述,其中包含有关云计算和 Windows Azure 的社区推动新闻.内容和对话.以下是本周的亮点. 文章.视频和博客文章 ·   Azure CDN:吸取的宝贵经验(10 月 ...

  7. poj 2593 Max Sequence(线性dp)

    题目链接:http://poj.org/problem?id=2593 思路分析:该问题为求给定由N个整数组成的序列,要求确定序列A的2个不相交子段,使这m个子段的最大连续子段和的和最大. 该问题与p ...

  8. [置顶] SQL日期类型

    在做机房收费系统的时候,上下机,我觉得是我在整个系统中遇到最棘手的问题了,现在就给大家,分享一下,我是怎样解决的. SQL中有3中数据类型是关于日期的,每一种的用法是不同的,当你用错了,就会出现下面这 ...

  9. 偶然碰到的Win7 64位下CHM 的问题解决

    最近下了几个沪江资料,都是chm格式的,但是在win7 64位下,都显示不了里面的音频和视频flash之类的控件,虽然可以通过源文件的方式打开视频文件,但是很麻烦.    网上似乎碰到的人也不是很多, ...

  10. 基于RYU控制器(controller)上的simple-switch 的APP做的測试-SDN/OpenFlow

    近期一直在学习RYU控制器,在使用的过程中,发现有下面几方面的长处:RYU控制器全然使用Python语言编写,在理解起来和上手速度上是挺快的:RYU控制器的总体架构清晰明了,在日后有时间我会整理一个关 ...