农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术。不幸的是,由于工程问题,每个牛栏都不一样。第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶。上个星期,农夫约翰刚刚收集到了奶牛们的爱好的信息(每头奶牛喜欢在哪些牛栏产奶)。一个牛栏只能容纳一头奶牛,当然,一头奶牛只能在一个牛栏中产奶。
给出奶牛们的爱好的信息,计算最大分配方案。
输入格式:
第一行 两个整数,N (0 <= N <= 200) 和 M (0 <= M <= 200) 。N 是农夫约翰的奶牛数量,M 是新牛棚的牛栏数量。
第二行到第N+1行 一共 N 行,每行对应一只奶牛。第一个数字 (Si) 是这头奶牛愿意在其中产奶的牛栏的数目 (0 <= Si <= M)。后面的 Si 个数表示这些牛栏的编号。牛栏的编号限定在区间 (1..M) 中,在同一行,一个牛栏不会被列出两次。
输出格式:
只有一行。输出一个整数,表示最多能分配到的牛栏的数量.
输入样例#1
5 5
2 2 5
3 2 3 4
2 1 5
3 1 2 5
1 2
输出样例#1:
4
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 }