题目描述
农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术。不幸的是,由于工程问题,每个牛栏都不一样。第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶。上个星期,农夫约翰刚刚收集到了奶牛们的爱好的信息(每头奶牛喜欢在哪些牛栏产奶)。一个牛栏只能容纳一头奶牛,当然,一头奶牛只能在一个牛栏中产奶。
给出奶牛们的爱好的信息,计算最大分配方案。
输入输出格式
输入格式:
第一行 两个整数,N (0 <= N <= 200) 和 M (0 <= M <= 200) 。N 是农夫约翰的奶牛数量,M 是新牛棚的牛栏数量。
第二行到第N+1行 一共 N 行,每行对应一只奶牛。第一个数字 (Si) 是这头奶牛愿意在其中产奶的牛栏的数目 (0 <= Si <= M)。后面的 Si 个数表示这些牛栏的编号。牛栏的编号限定在区间 (1..M) 中,在同一行,一个牛栏不会被列出两次。
输出格式:
只有一行。输出一个整数,表示最多能分配到的牛栏的数量.
输入输出样例
说明
N (0 <= N <= 200)
M (0 <= M <= 200)
网络流裸题
建一个超级源点,一个超级汇点
跑Dinic
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 const int MAXN=2*1e6+10; 8 const int INF=0x7fffff; 9 inline int read() 10 { 11 char c=getchar();int flag=1,x=0; 12 while(c<'0'||c>'9') {if(c=='-') flag=-1;c=getchar();} 13 while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();return x*flag; 14 } 15 struct node 16 { 17 int u,v,f,nxt; 18 }edge[MAXN]; 19 int head[MAXN],cur[MAXN]; 20 int num=0; 21 inline void add_edge(int x,int y,int z) 22 { 23 edge[num].u=x; 24 edge[num].v=y; 25 edge[num].f=z; 26 edge[num].nxt=head[x]; 27 head[x]=num++; 28 } 29 inline void add(int x,int y,int z) 30 { 31 add_edge(x,y,z); 32 add_edge(y,x,0); 33 } 34 int n,m,e; 35 int S=0,T=MAXN-1; 36 int deep[MAXN]; 37 inline bool BFS() 38 { 39 memset(deep,0,sizeof(deep)); 40 queue<int>q;q.push(S);deep[S]=1; 41 while(q.size()!=0) 42 { 43 int p=q.front();q.pop(); 44 for(int i=head[p];i!=-1;i=edge[i].nxt) 45 if(edge[i].f&&deep[edge[i].v]==0) 46 deep[edge[i].v]=deep[p]+1,q.push(edge[i].v); 47 } 48 return deep[T]; 49 } 50 int dfs(int now,int nowflow) 51 { 52 if(now==T||nowflow<=0) return nowflow; 53 int totflow=0; 54 for(int &i=cur[now];i!=-1;i=edge[i].nxt) 55 { 56 if(edge[i].f&&deep[edge[i].v]==deep[edge[i].u]+1) 57 { 58 int canflow=dfs(edge[i].v,min(edge[i].f,nowflow)); 59 totflow+=canflow; 60 nowflow-=canflow; 61 edge[i].f-=canflow; 62 edge[i^1].f+=canflow; 63 if(nowflow<=0) break; 64 } 65 } 66 return totflow; 67 } 68 inline void Dinic() 69 { 70 int ans=0; 71 while(BFS()) 72 { 73 memcpy(cur,head,sizeof(head)); 74 ans+=dfs(S,INF); 75 } 76 printf("%d",ans); 77 } 78 int main() 79 { 80 memset(head,-1,sizeof(head)); 81 n=read();m=read(); 82 for(int i=1;i<=n;i++) add(S,i,1); 83 for(int i=1;i<=m;i++) add(i+n,T,1); 84 for(int i=1;i<=n;i++) 85 { 86 int num=read(); 87 for(int j=1;j<=num;j++) 88 { 89 int how=read(); 90 add(i,how+n,1); 91 } 92 } 93 Dinic(); 94 return 0; 95 }