这里采用网络流方法解决,建立虚拟源点src,从src到每头牛添边,建立虚拟汇点des,从每个摊点向des添边,每条边的权值都是1,求从src到des的最大流即可
- #include <iostream>
- #include <algorithm>
- #include <string>
- #include <map>
- using namespace std;
- /*
- PROG: stall4
- LANG: C++
- ID: heben991
- */
- const int N = 420, INF = 2000000000, MaxFlow = 10000000;
- int g[N][N], flow[N][N];
- int n, cow, stall;
- int inc[N], q[N], pre[N];
- bool bfs(int src, int des)
- {
- int fp, rp, i, j, u;
- for(i = 0; i <= n; ++i) pre[i]=-1;
- inc[src] = INF;
- q[fp=rp=0] = src;
- while(fp<=rp)
- {
- u = q[fp++];
- for(i = 0; i <= n; ++i)
- if(pre[i]==-1 && flow[u][i] < g[u][i])
- {
- inc[i] = min(inc[u], g[u][i]-flow[u][i]);
- pre[i] = u;
- if(i==des) return true;
- q[++rp] = i;
- }
- }
- return false;
- }
- int Edmonds_Karp(int src, int des)
- {
- int i, j, maxflow=0;
- while(bfs(src,des))
- {
- for(i = des; i != src; i = pre[i])
- {
- j = pre[i];
- flow[j][i] += inc[i];
- flow[i][j] = -flow[j][i];
- }
- maxflow += inc[des];
- }
- return maxflow;
- }
- int main()
- {
- int i, j, k, x, y;
- freopen("stall4.in", "r", stdin);
- freopen("stall4.out","w",stdout);
- scanf("%d%d", &cow, &stall);
- for(i = 1; i <= cow; ++i)
- {
- scanf("%d", &x);
- for(j = 1; j <= x; ++j)
- {
- scanf("%d", &y);
- g[i][y+cow] = 1;
- }
- }
- for(i = 1; i <= cow; ++i) g[0][i] = 1;
- n = cow+stall+1;
- for(i = cow+1; i < n; ++i) g[i][n] = 1;
- printf("%d/n", Edmonds_Karp(0,n) );
- return 0;
- }