Poj_2396
The first time I came into contact with the Network Flow Problem of the upper and lower bounds, I felt that I had to follow the routine. The specificAlgorithmSee http://blog.csdn.net/water_glass/article/details/6823741.
# Include <stdio. h> # Include < String . H> # Include <Algorithm> # Define Maxn 210 # Define Maxm 30 # Define Maxv 230 # Define MaxE 24900 # Define INF 0x3f3f3f Int N, m, low [maxn] [maxm], high [maxn] [maxm], R [maxn], C [maxm]; Int S, T, SS, TT, first [maxv], E, next [MaxE], V [MaxE], flow [MaxE]; Int D [maxv], Q [maxv], work [maxv]; Int Id [maxn] [maxm]; Void Update ( Int X1, Int X2, Int Y1, Int Y2,Char Op, Int Z ){ Int I, J; For (I = x1; I <= x2; I ++ ) For (J = Y1; j <= Y2; j ++ ){ If (OP = ' = ' ) Low [I] [J] = STD: max (low [I] [J], Z), high [I] [J] =STD: min (high [I] [J], Z ); Else If (OP = ' < ' ) High [I] [J] = STD: min (high [I] [J], Z- 1 ); Else Low [I] [J] = STD: max (low [I] [J], Z + 1 );}} Void Init (){ Int I, J, K, X, Y, Z, N; Char OP [ 5 ]; Scanf ( " % D " , & N ,& M); memset (low, 0 , Sizeof (Low), memset (High, 0x3f , Sizeof (High )); For (I = 1 ; I <= N; I ++ ) Scanf ( " % D " ,& R [I]); For (I = 1 ; I <= m; I ++ ) Scanf ( " % D " ,& C [I]); scanf ( " % D " ,& N ); For (K = 0 ; K <n; k ++ ) {Scanf ( " % D % S % d " , & X, & Y, op ,& Z ); If (X = 0 & Y = 0 ) Update ( 1 , N, 1 , M, OP [ 0 ], Z ); Else If (X = 0 ) Update ( 1 , N, Y, Y, OP [ 0 ], Z ); Else If (Y = 0 ) Update (X, X, 1 , M, OP [ 0 ], Z ); Else Update (x, x, y, Y, OP [ 0 ], Z );}} Int Check (){ For ( Int I = 1 ; I <= N; I ++) For ( Int J = 1 ; J <= m; j ++) If (Low [I] [J]> high [I] [J]) Return 0 ; Return 1 ;} Void Add ( Int X, Int Y, Int Z) {v [E] = Y, flow [e] = Z; next [E] = First [X], first [x] = e ++ ;} Int Build (){ Int I, j, sum = 0 ; S = 0 , T = n + M + 1 , Ss = T + 1 , TT = SS + 1 ; Memset (first, - 1 , Sizeof (First [ 0 ]) * (TT + 1 ), E = 0 ; Add (t, s, INF), add (S, T, 0 ); For (I = 1 ; I <= N; I ++ ) {Add (SS, I, R [I]), add (I, SS, 0 ), Add (S, TT, R [I]), add (TT, S, 0 ); Sum + = R [I];} For (I = 1 ; I <= m; I ++) {Add (SS, T, C [I]), add (T, SS, 0 ), Add (n + I, TT, C [I]), add (TT, N + I, 0 ); Sum + = C [I];} For (I = 1 ; I <= N; I ++ ) For (J = 1 ; J <= m; j ++ ) {Add (I, n + J, high [I] [J]-low [I] [J]), Id [I] [J] = E, add (n + J, I, 0 ); Add (SS, n + J, low [I] [J]), add (n + J, SS, 0 ), Add (I, TT, low [I] [J]), add (TT, I, 0 ); Sum + = Low [I] [J];} Return SUM ;} Int BFS ( Int S, Int T ){ 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, Int T ){ 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]), t) {flow [I] -= T, flow [I ^ 1 ] + = T; Return T ;} Return 0 ;} Int Dinic ( Int S, Int T ){ Int Ans = 0 , T; While (BFS (S, T) {memcpy (work, first, Sizeof (First [ 0 ]) * (T + 1 )); While (T = DFS (S, INF, t) ans + = T ;} Return Ans ;} Void Print (){ Int I, J; For (I = 1 ; I <= N; I ++ ) {Printf ( " % D " , Flow [ID [I] [ 1 ] + Low [I] [ 1 ]); For (J =2 ; J <= m; j ++ ) Printf ( " % D " , Flow [ID [I] [J] + Low [I] [J]); printf ( " \ N " );}} Void Solve (){ If (! Check () {printf ( " Impossible \ n " ); Return ;} Int Sum = Build (); If (Sum! = Dinic (SS, TT) printf ( " Impossible \ n " ); Else Print ();} Int Main (){ Int T; scanf ( " % D " ,& T ); While (T -- ) {Init (); solve (); If (T) printf ( " \ N " );} Return 0 ;}