Matrix
Time Limit: 2000/1000 MS (Java/others) memory limit: 32768/32768 K (Java/Others)
Total submission (s): 1665 accepted submission (s): 901
Problem descriptionyifenfei very like play a number game in the N * n matrix. A positive integer number is put in each area of the matrix.
Every time yifenfei shocould To Do Is that choose a detour which frome the top left point to the bottom right point and than back to the top left point with the maximal values of sum integers that area matrix yifenfei choose. but from the top to the bottom can only choose right and down, from the bottom to the top can only choose left and up. and yifenfei can not pass the same area of the matrix before t the start and end.
Inputthe input contains multiple test cases.
Each case first line given the integer N (2 <n <30)
Than n lines, each line include n positive integers. (<100)
Outputfor each test case output the maximal values yifenfei can get.
Sample Input
210 35 10310 3 32 5 36 7 1051 2 3 4 52 3 4 5 63 4 5 6 74 5 6 7 85 6 7 8 9
Sample output
284680
From top left to bottom right, go back to top left, and each vertex can only go through once.
You can walk twice from top left to bottom right. As for each vertex, you can only walk once and split the vertex. The size of each vertex I to the corresponding I point is 1, so that the vertex can only walk once.
# Include <cstdio> # include <cstring> # include <queue> # include <algorithm> using namespace STD; # define maxn 3000 # define INF 0x3f3f3fstruct node {int V, W, s; int next;} p [3000000]; int A [50] [50], head [maxn], CNT; int pre [maxn], vis [maxn], dis [maxn]; queue <int> q; void add (int u, int V, int W, int s) {P [CNT]. V = V; P [CNT]. W = W; P [CNT]. S = s; P [CNT]. next = head [u]; head [u] = CNT ++; P [CNT]. V = U; P [CNT]. W = 0; P [CNT]. S =-S; P [CNT]. next = head [v]; head [v] = CNT ++;} int spfa (int s, int t) {int U, V, I; memset (DIS, INF, sizeof (DIS); DIS [s] = 0; vis [s] = 1; Pre [s] = pre [T] =-1; while (! Q. Empty () Q. Pop (); q. Push (s); While (! Q. Empty () {u = Q. Front (); q. Pop (); vis [u] = 0; for (I = head [u]; I! =-1; I = P [I]. next) {v = P [I]. v; If (P [I]. W & dis [v]> dis [u] + P [I]. s) {dis [v] = dis [u] + P [I]. s; Pre [v] = I; If (! Vis [v]) {vis [v] = 1; q. push (v) ;}}}if (pre [T] =-1) return 0; return 1;} void F (int s, int T) {memset (PRE,-1, sizeof (pre); memset (VIS, 0, sizeof (VIS); int I, ANS = 0, min1; while (spfa (S, T) {min1 = inf; for (I = pre [T]; I! =-1; I = pre [p [I ^ 1]. v]) if (P [I]. W <min1) min1 = P [I]. w; for (I = pre [T]; I! =-1; I = pre [p [I ^ 1]. v]) {P [I]. w-= min1; P [I ^ 1]. W + = min1; ans + = P [I]. s ;}} printf ("% d \ n",-ans) ;}int main () {int I, j, N, B, temp; while (scanf ("% d", & N )! = EOF) {/* is the same as D, but this question can only go through once for each vertex. It is required to go from top left to bottom right and then back to top left, it can be thought of as two times from top left to bottom right */memset (Head,-1, sizeof (head); CNT = 0; temp = N * n; for (I = 1; I <= N; I ++) for (j = 1; j <= N; j ++) {scanf ("% d ", & A [I] [J]); B = (I-1) * n + J; If (B = 1 | B = temp) add (B, B + temp,); // The Source and Sink are added twice (B, B + temp, 1,-A [I] [J]); // split the vertex so that each vertex can be processed only once.} For (I = 1; I <= N; I ++) for (j = 1; j <= N; j ++) {B = (I-1) * n + J; if (I> 1) Add (B-N + temp, B, 1, 0); If (j> 1) Add (B-1 + temp, B, );} Add (,); add (2 * n, 2 * n +, 0 ); F (* n + 1);} return 0 ;}