This question is hard to come up with on the network stream...
Increase the arc with a capacity of 1 from s to each item to Bob, and then increase the arc with a capacity of 1 from each item to t (representing the number of types ). When running the largest stream at this time, we will surely get the initial number of types owned by Bob. What is the maximum number after the switch?
For a friend other than Bob, if I had more than one j item (he kept at least one after the exchange), from the person node I to the item node j increased capacity to the num-1 of the arc, it indicates how many items can be output, and if I does not have j items, then increase the arc capacity of 1 from item node j to person node I (he can accept a maximum of 1 items ). Then the answer is obtained by running the largest stream.
#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<fstream>#include<sstream>#include<bitset>#include<vector>#include<string>#include<cstdio>#include<cmath>#include<stack>#include<queue>#include<stack>#include<map>#include<set>#define FF(i, a, b) for(int i=a; i<b; i++)#define FD(i, a, b) for(int i=a; i>=b; i--)#define REP(i, n) for(int i=0; i<n; i++)#define CLR(a, b) memset(a, b, sizeof(a))#define debug puts("**debug**")#define LL long long#define PB push_backusing namespace std;const int maxn = 300;const int INF = 1e9;int n, m, s, t, num[11][30];int d[maxn], cur[maxn];bool vis[maxn];struct Edge{ int from, to, cap, flow;};vector<Edge> edges;vector<int> G[maxn];void init(){ s = 0, t = n + m + 1; CLR(num, 0); REP(i, t+1) G[i].clear(); edges.clear();}void add(int from, int to, int cap){ edges.PB((Edge){from, to, cap, 0}); edges.PB((Edge){to, from, 0, 0}); int nc = edges.size(); G[from].PB(nc-2); G[to].PB(nc-1);}bool bfs(){ CLR(vis, 0); queue<int> q; q.push(s); d[s] = 0, vis[s] = 1; while(!q.empty()) { int x = q.front(); q.pop(); int nc = G[x].size(); REP(i, nc) { Edge e = edges[G[x][i]]; if(!vis[e.to] && e.cap > e.flow) { vis[e.to] = 1; d[e.to] = d[x] + 1; q.push(e.to); } } } return vis[t];}int dfs(int x, int a){ if(x == t || a == 0) return a; int flow = 0, f, nc = G[x].size(); for(int& i = cur[x]; i<nc; i++) { Edge& e = edges[G[x][i]]; if(d[x] + 1 == d[e.to] && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0) { e.flow += f; edges[G[x][i]^1].flow -= f; flow += f; a -= f; if(a == 0) break; } } return flow;}int max_flow(){ int flow = 0; while(bfs()) { CLR(cur, 0); flow += dfs(s, INF); } return flow;}int main(){ int T; scanf("%d", &T); FF(kase, 1, T+1) { scanf("%d%d", &n, &m); init(); int x; REP(i, n) { scanf("%d", &num[i][0]); while(num[i][0]--) { scanf("%d", &x); num[i][x]++; } } FF(i, 1, m+1) { if(num[0][i]) add(s, i+n, num[0][i]); add(i+n, t, 1); } FF(i, 1, n) { FF(j, 1, m+1) { if(num[i][j] > 1) add(i, j+n, num[i][j] - 1); if(num[i][j] == 0) add(j+n, i, 1); } } printf("Case #%d: %d\n", kase, max_flow()); } return 0;}