BZOJ 1711 [Usaco2007 Open]Dining吃饭
Posted Doggu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1711 [Usaco2007 Open]Dining吃饭相关的知识,希望对你有一定的参考价值。
1711: [Usaco2007 Open]Dining吃饭
Description
农夫JOHN为牛们做了很好的食品,但是牛吃饭很挑食. 每一头牛只喜欢吃一些食品和饮料而别的一概不吃.虽然他不一定能把所有牛喂饱,他还是想让尽可能多的牛吃到他们喜欢的食品和饮料. 农夫JOHN做了F (1 <= F <= 100) 种食品并准备了D (1 <= D <= 100) 种饮料. 他的N (1 <= N <= 100)头牛都以决定了是否愿意吃某种食物和喝某种饮料. 农夫JOHN想给每一头牛一种食品和一种饮料,使得尽可能多的牛得到喜欢的食物和饮料. 每一件食物和饮料只能由一头牛来用. 例如如果食物2被一头牛吃掉了,没有别的牛能吃食物2.
Input
* 第一行: 三个数: N, F, 和 D
* 第2..N+1行: 每一行由两个数开始F_i 和 D_i, 分别是第i 头牛可以吃的食品数和可以喝的饮料数.下F_i个整数是第i头牛可以吃的食品号,再下面的D_i个整数是第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
输入解释:
牛 1: 食品从 {1,2}, 饮料从 {1,2} 中选
牛 2: 食品从 {2,3}, 饮料从 {1,2} 中选
牛 3: 食品从 {1,3}, 饮料从 {1,2} 中选
牛 4: 食品从 {1,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
输入解释:
牛 1: 食品从 {1,2}, 饮料从 {1,2} 中选
牛 2: 食品从 {2,3}, 饮料从 {1,2} 中选
牛 3: 食品从 {1,3}, 饮料从 {1,2} 中选
牛 4: 食品从 {1,3}, 饮料从 {3} 中选
Sample Output
3
输出解释:
一个方案是:
Cow 1: 不吃
Cow 2: 食品 #2, 饮料 #2
Cow 3: 食品 #1, 饮料 #1
Cow 4: 食品 #3, 饮料 #3
用鸽笼定理可以推出没有更好的解 (一共只有3总食品和饮料).当然,别的数据会更难.
输出解释:
一个方案是:
Cow 1: 不吃
Cow 2: 食品 #2, 饮料 #2
Cow 3: 食品 #1, 饮料 #1
Cow 4: 食品 #3, 饮料 #3
用鸽笼定理可以推出没有更好的解 (一共只有3总食品和饮料).当然,别的数据会更难.
虽说是典型水题,但第一次提交时居然WA了。且让我们娓娓道来。
源点s到f种食物连一条容量为1的边,d种饮料到汇点t连一条容量为1的边。然后牛与对应的食物和饮料连边。
但是!牛是要拆的,因为牛也有专一性。最后,此题数据太水。
Accepted | 2428 kb | 8 ms |
1 /************************************************************** 2 Problem: 1711 3 User: Doggu 4 Language: C++ 5 Result: Accepted 6 Time:8 ms 7 Memory:2428 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <algorithm> 13 template<class T>inline void readin(T &res) { 14 static char ch;T flag=1; 15 while((ch=getchar())<‘0‘||ch>‘9‘)if(ch==‘-‘)flag=-1; 16 res=ch-48;while((ch=getchar())>=‘0‘&&ch<=‘9‘)res=(res<<1)+(res<<3)+ch-48;res*=flag; 17 } 18 19 const int N = 1000; 20 const int M = 100000; 21 struct Edge {int v,upre,cap,flow;}g[M]; 22 int head[N], ne=-1; 23 inline void adde(int u,int v,int cap) { 24 g[++ne]=(Edge){v,head[u],cap,0};head[u]=ne; 25 g[++ne]=(Edge){u,head[v],0,0};head[v]=ne; 26 } 27 28 #include <queue> 29 std::queue<int> q; 30 int n, f, dr, s, t, d[N], cur[N]; 31 bool BFS() { 32 while(!q.empty()) q.pop(); 33 memset(d,0,sizeof(d)); 34 q.push(s);d[s]=1; 35 while(!q.empty()) { 36 int u=q.front();q.pop(); 37 for( int i = head[u]; i != -1; i = g[i].upre ) { 38 int v=g[i].v; 39 if(!d[v]&&g[i].cap>g[i].flow) q.push(v), d[v]=d[u]+1; 40 } 41 } 42 return d[t]; 43 } 44 int DFS(int u,int a) { 45 if(u==t||a==0) return a; 46 int flow=0, f; 47 for( int &i = cur[u]; i != -1; i = g[i].upre ) { 48 int v=g[i].v; 49 if(d[v]==d[u]+1&&(f=DFS(v,std::min(a,g[i].cap-g[i].flow)))>0) { 50 flow+=f;a-=f; 51 g[i].flow+=f;g[i^1].flow-=f; 52 if(a==0) break; 53 } 54 } 55 if(flow==0) d[u]=0; 56 return flow; 57 } 58 void maxflow() { 59 int flow=0; 60 while(BFS()) { 61 memcpy(cur,head,sizeof(head)); 62 flow+=DFS(s,0x3f3f3f3f); 63 } 64 printf("%d\n",flow); 65 } 66 67 int main() { 68 memset(head,-1,sizeof(head)); 69 readin(n);readin(f);readin(dr);s=0;t=f+n*2+dr+1; 70 for( int i = 1; i <= f; i++ ) adde(s,i,1); 71 for( int i = 1; i <= n; i++ ) adde(f+i,f+n+i,1); 72 for( int i = 1; i <= dr; i++ ) adde(f+n*2+i,t,1); 73 for( int i = 1, a, b, c; i <= n; i++ ) { 74 readin(a);readin(b); 75 for( int j = 1; j <= a; j++ ) { 76 readin(c); 77 adde(c,f+i,1); 78 } 79 for( int j = 1; j <= b; j++ ) { 80 readin(c); 81 adde(f+n+i,f+n*2+c,1); 82 } 83 } 84 maxflow(); 85 return 0; 86 } 87
以上是关于BZOJ 1711 [Usaco2007 Open]Dining吃饭的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1711 [Usaco2007 Open]Dining吃饭
bzoj 1711: [Usaco2007 Open]Dining吃饭
BZOJ1711: [Usaco2007 Open]Dining吃饭
bzoj1711: [Usaco2007 Open]Dining吃饭