// Starting from the beginning. // Network stream solution. If the maximum stream is the sum of all elements, the solution is available. The residual network is used to determine whether it is unique. // There are two methods, the first is to perform a deep search to check whether a ring with positive Edge Weight exists. For details, see the ring consisting of 4888 // at least three points in the previous article. The second is to use matrix DP, only the I column elements of a row <9, J column elements> 0, while the I column elements of the other row> 0, J column elements <9, // if they can meet the complementary requirements, it proves that they are not unique. This drawing is not difficult to see # include <stdio. h> # include <string. h ># include <queue> using namespace STD; # define INF 0x3fffffff # define n 1100 struct node {int U, V, W, next ;} bian [N * n * 4]; int head [N], Yong, DIS [N], work [N]; void Init () {Yong = 0; memset (Head, -1, sizeof (head);} void addbian (int U, int V, int W) {Bian [Yong]. U = u; Bian [Yong]. V = V; Bian [Yong]. W = W; Bian [Yong]. next = head [u]; head [u] = Yong ++;} void add (int u, int V, int W) {addbian (U, V, W ); addbian (v, U, 0);} int min (int A, int B) {return a <B? A: B;} int BFS (INT S, int t) {memset (DIS,-1, sizeof (DIS); queue <int> q; q. push (s); DIS [s] = 0; while (! Q. Empty () {int u = Q. Front (); q. Pop (); For (INT I = head [u]; I! =-1; I = Bian [I]. next) {int v = Bian [I]. v; If (Bian [I]. W & dis [v] =-1) {dis [v] = dis [u] + 1; q. push (V); If (V = T) return 1 ;}} return 0 ;}int DFS (int s, int limit, int T) {If (S = T) return limit; For (Int & I = work [s]; I! =-1; I = Bian [I]. next) {int v = Bian [I]. v; If (Bian [I]. W & dis [v] = dis [s] + 1) {int TT = DFS (v, min (limit, Bian [I]. w), T); If (TT) {Bian [I]. w-= tt; Bian [I ^ 1]. W + = tt; return TT ;}}return 0 ;}int dinic (int s, int t) {int ans = 0; while (BFS (S, T )) {memcpy (work, Head, sizeof (head); While (int tt = DFS (S, INF, t) ans + = tt;} return ans ;} int f [N], FF [N], DP [N] [N], ma [N] [N]; int judge (int n, int m) {int I, j, k; memset (DP, 0, sizeof (DP); for (I = 1; I <= N; I ++) for (j = head [I]; J! =-1; j = Bian [J]. next) {int v = Bian [J]. v; If (V> N & V <= N + M) Ma [I] [V-N] = Bian [J ^ 1]. W ;}for (I = 1; I <= N; I ++) {If (F [I] = 0 | f [I] = 9 * m) continue; For (j = 1; j <= m; j ++) {If (FF [J] = 0 | FF [J] = 9 * n) continue; For (k = J + 1; k <= m; k ++) {int flag1 = 0, flag2 = 0; if (MA [I] [J]> 0 & Ma [I] [k] <9) {If (DP [k] [J]) return 1; flag1 = 1;} If (MA [I] [J] <9 & Ma [I] [k]> 0) {If (DP [J] [k]) return 1; flag2 = 1;} If (flag1) DP [J] [k] = 1; if (flag2) DP [k] [J] = 1 ;}}} Return 0;} int main () {int M, I, j, S, N, T, Suma, K, sumb, T, cou = 0; scanf ("% d", & T); While (t --) {scanf ("% d", & N, & M); k = 9; S = 0; t = n + m + 1; Init (); Suma = 0; sumb = 0; for (I = 1; I <= N; I ++) {scanf ("% d", & F [I]); Suma + = f [I]; add (S, I, F [I]);} for (I = 1; I <= m; I ++) {scanf ("% d", & FF [I]); sumb + = FF [I]; add (I + N, T, FF [I]) ;}for (I = 1; I <= N; I ++) for (j = 1; j <= m; j ++) add (I, j + n, k); If (SUMA! = Sumb) {printf ("case # % d: so naive! \ N ", ++ cou); continue;} k = dinic (S, T); If (K! = SUMA) {printf ("case # % d: so naive! \ N ", ++ cou); continue;} k = judge (n, m); // printf (" % d \ n ", k); If (k) printf ("case # % d: so young! \ N ", ++ cou); else printf (" case # % d: so simple! \ N ", ++ cou);} return 0 ;}
The maximum stream of HDU 4975 solves the problem of columns and matrix calculation, and uses matrix DP optimization.