Dining(最大流)

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种喝的,吃的和喝的只能被用一次,求可以满足的母牛个数;

这个题可以加一个源点,一个终点,将吃的左边与源点连,右边与母牛连,将母牛拆点,母牛右边与喝的连,喝的与终点连。。。

代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<queue>
 6 #include<algorithm>
 7 #define mem(x,y) memset(x,y,sizeof(x))
 8 using namespace std;
 9 const int INF=0x3f3f3f3f;
10 const int MAXN=410;
11 const int MAXM=50010<<1;
12 int head[MAXM];
13 int vis[MAXN],dis[MAXN];
14 int edgnum;
15 struct Node{
16     int from,to,next,cup,flow;
17 };
18 Node edg[MAXM];
19 queue<int>dl;
20 void add(int u,int v,int w){
21     Node E={u,v,head[u],w,0};
22     edg[edgnum]=E;
23     head[u]=edgnum++;
24     E={v,u,head[v],0,0};
25     edg[edgnum]=E;
26     head[v]=edgnum++;
27 }
28 void initial(){
29     mem(head,-1);edgnum=0;
30 }
31 bool bfs(int s,int e){
32     mem(vis,0);mem(dis,-1);
33     while(!dl.empty())dl.pop();
34     dis[s]=0;vis[s]=1;dl.push(s);
35     while(!dl.empty()){
36         int u=dl.front();
37         dl.pop();
38         for(int i=head[u];i!=-1;i=edg[i].next){
39             Node v=edg[i];
40             if(!vis[v.to]&&v.cup>v.flow){
41                 vis[v.to]=1;dl.push(v.to);
42                 dis[v.to]=dis[u]+1;
43                 if(v.to==e)return true;
44             }
45         }
46     }
47     return false;
48 }
49 int dfs(int x,int la,int e){
50     if(x==e||la==0)return la;
51     int temp;
52     int flow=0;
53     for(int i=head[x];i!=-1;i=edg[i].next){
54         Node &v=edg[i];
55         if(dis[v.to]==dis[x]+1&&(temp=dfs(v.to,min(la,v.cup-v.flow),e))>0){
56             v.flow+=temp;
57             edg[i^1].flow-=temp;
58             la-=temp;
59             flow+=temp;
60             if(la==0)break;
61         }
62     }
63     return flow;
64 }
65 int maxflow(int s,int e){
66     int flow=0;
67     while(bfs(s,e)){
68         flow+=dfs(s,INF,e);
69     }
70     return flow;
71 }
72 int main(){
73     int n,F,D,f,d,a,b;
74     while(~scanf("%d%d%d",&n,&F,&D)){
75         initial();
76         for(int i=1;i<=n;i++){
77             scanf("%d%d",&f,&d);
78             while(f--){
79                 scanf("%d",&a);
80                 add(2*n+a,i,1);
81             }
82             while(d--){
83                 scanf("%d",&a);
84                 add(n+i,2*n+F+a,1);
85             }
86             add(i,n+i,1);
87         }
88         for(int i=1;i<=F;i++)add(0,2*n+i,1);
89         for(int i=1;i<=D;i++)add(2*n+F+i,2*n+F+D+1,1);
90         printf("%d\n",maxflow(0,2*n+F+D+1));//醉了,应该从0开始,找了半天错。。。
91     }
92     return 0;
93 }

另一种解法超时:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<queue>
 6 #include<algorithm>
 7 #define mem(x,y) memset(x,y,sizeof(x))
 8 using namespace std;
 9 const int INF=0x3f3f3f3f;
10 const int MAXN=500;
11 const int MAXM=50010<<1;
12 queue<int>dl;
13 int vis[MAXN],map[MAXN][MAXN],pre[MAXN];
14 bool bfs(int s,int e){
15     mem(vis,0);mem(pre,-1);
16     vis[s]=1;dl.push(s);
17     int a;
18     while(!dl.empty()){
19         a=dl.front();
20         dl.pop();//忘写pop了。。。
21         if(a==e)return true;
22         for(int i=0;i<=e;i++){
23             if(!vis[i]&&map[a][i]){
24                 vis[i]=1;
25                 pre[i]=a;
26                 dl.push(i);
27                 //if(i==e)return true;
28             }
29         }
30     }
31     return false;
32 }
33 int maxflow(int s,int e){
34     int flow=0;
35     while(bfs(s,e)){
36         int temp=INF;
37         int r=e;
38         //puts("fasf");
39         while(r!=s)temp=min(temp,map[pre[r]][r]),r=pre[r];
40         r=e;
41         while(r!=s)map[pre[r]][r]-=temp,map[r][pre[r]]+=temp,r=pre[r];
42         flow+=temp;
43     }
44     return flow;
45 }
46 int main(){
47     int n,F,D,f,d,a,b;
48     while(~scanf("%d%d%d",&n,&F,&D)){
49         mem(map,0);
50         for(int i=1;i<=n;i++){
51             scanf("%d%d",&f,&d);
52             while(f--){
53                 scanf("%d",&a);
54             //    add(2*n+a,i,1);
55                 map[2*n+a][i]=1;
56             }
57             while(d--){
58                 scanf("%d",&a);
59             //    add(n+i,2*n+F+a,1);
60                 map[n+i][2*n+F+a]=1;
61             }
62             //add(i,n+i,1);
63             map[i][n+i]=1;
64         }
65         for(int i=1;i<=F;i++)map[0][2*n+i]=1;//add(0,2*n+i,1);
66         for(int i=1;i<=D;i++)map[2*n+F+i][2*n+F+D+1]=1;//add(2*n+F+i,2*n+F+D+1,1);
67         printf("%d\n",maxflow(0,2*n+F+D+1));//醉了,应该从0开始,找了半天错。。。
68     }
69     return 0;
70 } 
时间: 2024-12-05 00:53:00

Dining(最大流)的相关文章

POJ 3281 Dining (最大流)

Dining Time Limit: 2000MS   Memory Limit: 65536K       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

POJ 3281 Dining 最大流 Dinic算法

Dining Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10768   Accepted: 4938 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 fabulo

POJ 3281 Dining(最大流)

POJ 3281 Dining 题目链接 题意:n个牛,每个牛有一些喜欢的食物和饮料,每种食物饮料只有一个,问最大能匹配上多少只牛每个牛都能吃上喜欢的食物和喜欢的饮料 思路:最大流,建模源点到每个食物连一条边,容量为1,每个饮料向汇点连一条边容量为1,然后由于每个牛有容量1,所以把牛进行拆点,然后食物连向牛的入点,牛的出点连向食物,跑一下最大流即可 代码: #include <cstdio> #include <cstring> #include <queue> #in

[POJ3281]Dining 最大流(建图奇葩)

题目链接:http://poj.org/problem?id=3281 参考了某犇做的PPT.对于此题的解释有如下内容(我只是搬运工). [题目大意] 有F种食物和D种饮料,每种食物或饮料只能供一头牛享用,且每头牛只享用一种食物和一种饮料.现在有N头牛,每头牛都有自己喜欢的食物种类列表和饮料种类列表,问最多能使几头牛同时享用到自己喜欢的食物和饮料.(1 <= F <= 100, 1 <= D <= 100, 1 <= N <= 100) 此题的建模方法比较有开创性.以往

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

我是按照图论500题的文档来刷题的,看了这题怎么也不觉得这是最大流的题目.这应该是题目做得太少的缘故. 什么是最大流问题?最大流有什么特点? 最大流的特点我觉得有一下几点: 1.只有一个起点.一个终点.如果不是,我们可以构造超级源点,超级汇点. 2.边的容量有上限(有上下限的是另外一种特殊的最大流). 3.最后求的是一个最大值. 这题可以找到一些影子,一头奶牛只能吃一种食物,喝一种饮料.如果只有一种限制我们能很快反应过来(二分最大匹配),但是两种限制就增加了难度.不过还是可以理解为对边的权值的限

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

不使用二分图匹配,使用最大流即可,设源点S与汇点T,S->食物->牛->牛->饮料->T,每条边流量为1,因为流过牛的最大流量是1,所以将牛拆成两个点. 前向星,Dinic,复杂度:O(V2E) 直接套用模板 #include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<set

POJ3281 Dining 最大流

题意:有f种菜,d种饮品,每个牛有喜欢的一些菜和饮品,每种菜只能被选一次,饮品一样,问最多能使多少头牛享受自己喜欢的饮品和菜 分析:建边的时候,把牛拆成两个点,出和入 1,源点向每种菜流量为1 2,每种菜连所有喜欢这道菜的牛的入点,流量1 3,每头牛的入点和出点,流量为1 4,每头牛的出点连所有它喜欢的饮品,流量为1 5,每种饮品连汇点,流量为1 然后最大流是答案,这个题一定要拆点,因为一头牛只吃一次 注:模板采用的是LRJ大白书上的模板 #include <iostream> #includ

POJ-3281 Dining 最大流 拆点

题目链接:https://cn.vjudge.net/problem/POJ-3281 题意 题意找kuangbin的用了. 有N头牛,F个食物,D个饮料. N头牛每头牛有一定的喜好,只喜欢几个食物和饮料. 每个食物和饮料只能给一头牛.一头牛只能得到一个食物和饮料. 而且一头牛必须同时获得一个食物和一个饮料才能满足.问至多有多少头牛可以获得满足. 思路 建图如下就完事了: 提交过程 AC 代码 #include <queue> #include <cstdio> #include

题单二:图论500

http://wenku.baidu.com/link?url=gETLFsWcgddEDRZ334EJOS7qCTab94qw5cor8Es0LINVaGMSgc9nIV-utRIDh--2UwRLvsvJ5tXFjbdpzbjygEdpGehim1i5BfzYgYWxJmu ==========  以下是最小生成树+并查集=========================[HDU]1213         How Many Tables        基础并查集★1272         小

图论五百题!

生死看淡不服就淦,这才是人生! =============================以下是最小生成树+并查集======================================[HDU]1213 How Many Tables 基础并查集★1272 小希的迷宫 基础并查集★1325&&poj1308 Is It A Tree? 基础并查集★1856 More is better 基础并查集★1102 Constructing Roads 基础最小生成树★1232 畅通工程 基