Question link: Click the open link
Question: whitelists p370
Ideas:
Because the total number of last pasters is asked, the total number of pasters is the answer to the network flow.
First, we simulate the flow of stickers:
Bob's Paster A-> to a person without a Paster peo-> to bob a PEO's repeated Paster-> This Paster can be regarded as the answer.
# Include <stdio. h> # include <string. h> # include <iostream> # include <algorithm> # include <vector> # include <queue> using namespace STD; # define ll intconst int maxn = 100010; // maximum number of points const int maxm = 400010; // maximum number of edges # define n maxn # define M maxmconst int INF = 0x3f3f3f; # define INF infstruct edge {ll from, to, Cap, NEX;} edge [M * 2]; // note that this must be large enough. Otherwise, re will have reverse arc ll head [N], edgenum; void add (ll u, ll V, ll cap, ll RW = 0 ){ // If it is a directed edge, add (u, v, CAP); if it is a undirected edge, add (u, v, Cap, CAP ); edge e = {u, v, Cap, head [u]}; edge [edgenum] = E; head [u] = edgenum ++; edge e2 = {v, U, RW, head [v]}; edge [edgenum] = e2; head [v] = edgenum ++;} ll sign [N]; bool BFS (LL from, ll) {memset (sign,-1, sizeof (sign); Sign [from] = 0; queue <ll> q; q. push (from); While (! Q. Empty () {ll u = Q. Front (); q. Pop (); For (ll I = head [u]; I! =-1; I = edge [I]. NEX) {ll v = edge [I]. to; If (sign [v] =-1 & edge [I]. CAP) {sign [v] = sign [u] + 1, Q. push (V); If (sign [to]! =-1) return true ;}}return false;} ll stack [N], top, cur [N]; ll dinic (LL from, ll) {ll ans = 0; while (BFS (from, to) {memcpy (cur, Head, sizeof (head); LL u = from; Top = 0; while (1) {If (u = to) {ll flow = inf, Loc; // loc indicates the minimum cap edge in the stack for (ll I = 0; I <top; I ++) if (flow> edge [stack [I]. CAP) {flow = edge [stack [I]. CAP; loc = I ;}for (ll I = 0; I <top; I ++) {edge [stack [I]. cap-= flow; edge [stack [I] ^ 1]. cap + = flow;} ans + = flow; Top = LOC; u = edge [stack [Top]. from;} For (ll I = cur [u]; I! =-1; cur [u] = I = edge [I]. NEX) // cur [u] indicates the subscript if (edge [I] of the edge where the U is located. cap & (sign [u] + 1 = sign [edge [I]. to]) break; If (cur [u]! =-1) {stack [top ++] = cur [u]; u = edge [cur [u]. to;} else {If (Top = 0) break; sign [u] =-1; u = edge [stack [-- top]. from ;}}return ans;} void Init () {memset (Head,-1, sizeof head); edgenum = 0;} int n, m, K, S, t; int A [30]; void go () {int X; scanf ("% d", & X); memset (A, 0, sizeof ); while (X --) {int y; scanf ("% d", & Y); A [y] ++ ;}} void solve () {Init (); scanf ("% d", & N, & M); S = 1, t = n + m + 1; go (); For (INT I = 1; I <= m; I ++) if (a [I]) add (S, N + I, a [I]); For (INT I = 2; I <= N; I ++) {go (); For (Int J = 1; j <= m; j ++) if (A [J]-1> 0) add (I, n + J, a [J]-1); else if (a [J] = 0) add (n + J, I, 1) ;}for (INT I = 1; I <= m; I ++) add (n + I, T, 1 ); printf ("% d \ n", dinic (S, T);} int main () {int T, CAS = 1; scanf ("% d ", & T); While (t --) {printf ("case # % d:", CAS ++); solve ();} return 0 ;}
Create a diagram of the network flow + by using the web pages of the application server of the application.