Spoj_1693 coconuts
There are two types of choices for each person. Based on their final choice, they can be divided into two sets. Obviously, if there is a friend between the sets, the edge should be deleted, this actually forms a cut, corresponding to the number of friends with different opinions. In order to reflect the cost of changing your opinion, you can connect S and all the people who start to select 1 to an edge with a capacity of 1, then, a person and T with a capacity of 1 will be connected, and the edge of the friend relationship will be a undirected edge with a capacity of 1.In this way, the final result can be obtained by finding the minimum cut for this graph.
# Include <stdio. h> # Include < String . H> # Include <Algorithm> # Define Maxd 310 # Define Maxm 90610 # Define INF 0x3f3f3fInt N, m, first [maxd], E, next [maxm], V [maxm], flow [maxm]; Int S, T, d [maxd], Q [maxd], work [maxd]; Void Add ( Int X, Int Y, Int Z) {v [E] = Y, flow [e] = Z; next [E] = First [X], first [x] = e ++ ;} Void Init (){ Int I, X, Y; s = 0 , T = n + 1 ; Memset (first, - 1 , Sizeof (First [ 0 ]) * (T + 1 ); E = 0 ; For (I = 1 ; I <= N; I ++) {Scanf ( " % D " ,& X ); If (X) add (S, I, 1 ), Add (I, S, 0 ); Else Add (I, T, 1 ), Add (t, I, 0 );} For (I = 0 ; I <m; I ++ ) {Scanf ( " % D " , & X ,& Y); add (x, y, 1 ), Add (Y, X, 1 );}} Int BFS (){ Int I, j, rear = 0 ; Memset (D, - 1 , Sizeof (D [ 0 ]) * (T + 1 ); D [s] = 0 , Q [rear ++] = S; For (I = 0 ; I <rear; I ++ ) For (J = first [Q [I]; J! =- 1 ; J =Next [J]) If (Flow [J] & D [V [J] =- 1 ) {D [V [J] = D [Q [I] + 1 , Q [rear ++] = V [J]; If (V [J] = T) Return 1 ;} Return 0 ;} Int DFS ( Int Cur, Int A ){ If (Cur = T) Return A; For ( Int & I = work [cur]; I! =- 1 ; I = Next [I]) If (Flow [I] & D [V [I] = d [cur] + 1 ) If ( Int T = DFS (V [I], STD: min (A, flow [I]) {flow [I] -= T, flow [I ^ 1 ] + = T; Return T ;} Return 0 ;} Int Dinic (){ Int Ans =0 , T; While (BFS () {memcpy (work, first, Sizeof (First [ 0 ]) * (N + 1 )); While (T = DFS (S, INF) ans + = T ;} Return Ans ;} Void Solve () {printf ( " % D \ n " , Dinic ());} Int Main (){ While (Scanf ( " % D " , & N, & M), N | M) {Init (); solve ();} Return 0 ;}