bzoj1711: [Usaco2007 Open]Dining吃饭

建图后跑最大流即可

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define clr(x,c) memset(x,c,sizeof(x))
#define qwq(x) for(edge *o=head[x];o;o=o->next)
const int nmax=505;
const int maxn=40005;
const int inf=0x7f7f7f7f;
int read(){
	int x=0;char c=getchar();bool f=true;
	while(!isdigit(c)){
		if(c=='-') f=false;c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return f?x:-x;
}
struct edge{
	int to,cap;edge *next,*rev;
};
edge edges[maxn],*pt,*head[nmax],*cur[nmax],*p[nmax];
void add(int u,int v,int w){
	pt->to=v;pt->cap=w;pt->next=head[u];head[u]=pt++;
}
void adde(int u,int v,int w){
	add(u,v,w);add(v,u,0);head[u]->rev=head[v];head[v]->rev=head[u];
}
int cnt[nmax],h[nmax];
int maxflow(int s,int t,int n){
	clr(cnt,0);cnt[0]=n;clr(h,0);
	int flow=0,a=inf,x=s;edge *e;
	while(h[s]<n){
		for(e=cur[x];e;e=e->next) if(e->cap>0&&h[x]==h[e->to]+1) break;
		if(e){
			p[e->to]=cur[x]=e;a=min(a,e->cap);x=e->to;
			if(x==t){
				while(x!=s) p[x]->cap-=a,p[x]->rev->cap+=a,x=p[x]->rev->to;
				flow+=a,a=inf;
			}
		}else{
			if(!--cnt[h[x]]) break;
			h[x]=n;
			for(e=head[x];e;e=e->next) if(e->cap>0&&h[x]>h[e->to]+1) cur[x]=e,h[x]=h[e->to]+1;
			cnt[h[x]]++;
			if(x!=s) x=p[x]->rev->to;
		}
	}
	return flow;
}
int main(){
	pt=edges;clr(head,0);
	int n=read(),F=read(),D=read(),u,v,s=0,t=F+D+n+n+1;
	rep(i,n){
		adde(F+i,F+n+i,1);
		u=read(),v=read();
		rep(j,u) adde(read(),F+i,1);
		rep(j,v) adde(F+n+i,F+n+n+read(),1);
	}
	rep(i,F) adde(s,i,1);
	rep(i,D) adde(F+n+n+i,t,1);
	printf("%d
",maxflow(s,t,t+1));
	return 0;
}

 

1711: [Usaco2007 Open]Dining吃饭

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 815  Solved: 422
[Submit][Status][Discuss]

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} 中选

Sample Output

3
输出解释:

一个方案是:
Cow 1: 不吃
Cow 2: 食品 #2, 饮料 #2
Cow 3: 食品 #1, 饮料 #1
Cow 4: 食品 #3, 饮料 #3
用鸽笼定理可以推出没有更好的解 (一共只有3总食品和饮料).当然,别的数据会更难.

HINT

 

Source

[Submit][Status][Discuss]
原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5658545.html