Hdu_3338
As for how to create a picture, you can find it in other blogs (the problem solving of network streams is really hard to write, so this time I am so lazy ......), However, it is worth mentioning that, as most blogs have said, each blank grid must be connected to the run edge of the competent line and the run edge of the competent column, in fact, you only need to connect the run of the corresponding governing row to the run edge of the corresponding governing column. This edge represents this blank grid, the flow of traffic is the number to be filled in this grid.
# Include <stdio. h> # Include < String . H> # Include <Algorithm> # Define Maxd 20010 # Define Maxn 110 # Define Maxm 60010 # Define INF 0x3f3f3fInt N, m, first [maxd], E, next [maxm], V [maxm], flow [maxm], Id [maxn] [maxn]; Int S, T, d [maxd], work [maxd], Q [maxd]; Int R, C, G [maxn] [maxn], right [maxn] [maxn], down [maxn] [maxn], RID [maxn] [maxn], CID [maxn] [maxn]; Char B [ 10 ]; Void Init (){ Int I, J, K; memset (G, 0 , Sizeof (G )); For (I = 1 ; I <= N; I ++ ) For (J = 1 ; J <= m; j ++ ) {Scanf ( " % S " , B ); If (B [ 0 ] =' . ' ) G [I] [J] = 1 ; Else If (B [ 3 ]! = ' X ' ) {B [ 3 ] = ' \ 0 ' ; G [I] [J] = Down [I] [J] = right [I] [J] =- 1 ; If (B [ 0 ]! = ' X ' ) Sscanf (B, " % D " ,& Down [I] [J]); If (B [ 4 ]! =' X ' ) Sscanf (B + 4 , " % D " ,& Right [I] [J]) ;}} R = C = 0 ; Memset (RID, 0 , Sizeof (RID); memset (CID, 0 , Sizeof (CID )); For (I = 1 ; I <= N; I ++ ) For (J = 1 ; J <= m; j ++ ) If (G [I] [J] = 1 ){ If (! Rid [I] [J]) { ++ R; For (K = J; k <= M & G [I] [k] = 1 ; K ++) RID [I] [k] = R;} right [I] [J - 1 ]-= K- J; If (! CID [I] [J]) { ++ C; For (K = I; k <= N & G [k] [J] = 1 ; K ++) CID [k] [J] = C;} down [I - 1 ] [J]-= k- I ;}} Void Add ( Int X, Int Y, Int Z) {v [E] = Y, flow [e] = Z; next [E] = First [X], first [x] = e ++ ;} Void Build (){ Int I, J, K, P; s =0 , T = R + C + 1 ; Memset (first, - 1 , Sizeof (First [ 0 ]) * (T + 1 ), E = 0 ; For (I = 1 ; I <= N; I ++ ) For (J = 1 ; J <= m; j ++ ) If (G [I] [J] = 1 ) {ID [I] [J] = E; add (RID [I] [J], R + CID [I] [J], 8 ), Add (R + CID [I] [J], RID [I] [J], 0 );} For (I = 1 ; I <= N; I ++ ) For (J =1 ; J <= m; j ++ ) If (G [I] [J] =- 1 ){ If (Right [I] [J]! =- 1 ) P = Rid [I] [J + 1 ], Add (S, P, right [I] [J]), add (P, S, 0 ); If (Down [I] [J]! =- 1 ) P = CID [I + 1 ] [J], add (R + P, T, down [I] [J]), add (T, R + P, 0 );}} 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 ]) * (T + 1 )); While (T = DFS (S, INF) ans + = T ;} Return Ans ;} Void Solve (){ Int I, J; build (); dinic (); For (I = 1 ; I <= N; I ++ ){ For (J = 1 ; J <= m; j ++){ If (J! = 1 ) Printf ( " " ); If (G [I] [J] = 1 ) Printf ( " % D " , Flow [ID [I] [J] ^ 1 ] + 1 ); Else Printf ( " _ " );} Printf ( " \ N " );}} Int Main (){ While (Scanf ( " % D " , & N, & M) = 2 ) {Init (); solve ();} Return 0 ;}