0 or 1
Time Limit: 4000/2000 MS (Java/others) memory limit: 32768/32768 K (Java/Others)
Total submission (s): 692 accepted submission (s): 185
Problem descriptiongiven a n * n matrix CIJ (1 <= I, j <= N), we want to find a n * n matrix Xij (1 <= I, j <= N), which is 0 or 1.
Besides, Xij meets the following conditions:
1. X12 + x13 +... x1n = 1
2. x1n + x2n +... Xn-1n = 1
3. For each I (1 <I <n), satisfies Σ xki (1 <= k <= n) = Σ Xij (1 <= j <= N ).
For example, if n = 4, we can get the following running ity:
X12 + x13 + x14 = 1
X14 + x24 + x34 = 1
X12 + x22 + x32 + x42 = X21 + x22 + x23 + x24
X13 + x23 + x33 + x43 = x31 + x32 + x33 + x34
Now, we want to know the minimum of Σ CIJ * Xij (1 <= I, j <= N) you can get.Hint
For sample, X12 = x24 = 1, all other Xij is 0.
Inputthe input consists of multiple test cases (less than 35 case ).
For each test case, the first line contains one integer N (1 <n <= 300 ).
The next n lines, for each lines, each of which contains N integers, please strating the matrix C, the J-th integer on I-th line is CIJ (0 <= CIJ <= 100000 ).
Outputfor each case, output the minimum of Σ CIJ * Xij you can get.
Sample input4 1 2 4 10 2 0 1 1 2 2 0 5 6 3 1 2
Sample output3
Authorsnow_storm
Source2012 multi-university training contest 8
Recommendzhuyuanchen520
1001 (updated)
Obviously, the question is a 0/1 planning model.
The key to solving the problem lies in how to identify the nature of this model.
The three conditions clearly depict the relationship between unknown numbers. From the perspective of graph theory, we can easily draw the following three conclusions:
1. X12 + x13 +... x1n = 1 so the outbound degree of Node 1 is 1
2. x1n + x2n +... Xn-1n = 1 so the N node is 1
3. Sigma xki = Sigma Xij is equivalent to 2 ~ The inbound level of node n-1 must be equal to the outbound level.
Therefore, the three conditions are equivalent to a path from node 1 to node N. Therefore, Xij = 1 indicates that the edge must pass through (I, j) at the cost of CIJ. Xij = 0 indicates no passing edge (I, j ). Note that CIJ is non-negative and the question requires the minimum total cost. Therefore, the optimal answer path must correspond to a simple path.
In the end, we directly read the edge weight's Adjacent matrix and run the 1 to n shortest path.
In the above case, set it to
Very, very sorry. Simple paths are only adequate, but not necessary. (Sorry for the team that caused the problem)
B:
Starting from 1, taking a ring (at least one point, that is, not a self-ring) and returning to 1; Starting from N, taking a ring (likewise) and returning to n.
It is easy to verify, which meets the requirements of the question. And a | B is a sufficient condition for this question.
Because the edge weight is not negative, the two rings correspond to two simple rings.
Therefore, we can start from 1 and find a minimum cost loop with the cost of C1, and then start from N to find a minimum cost loop with the cost of C2. (In the shortest pathAlgorithmAdd another record when updating the weight: if (I = s) CIR = min (CIR, DIS [u] + G [u] [I])
Therefore, the final answer is Min (path, C1 + C2)
/* HDU 4370 0 or 1 refers to the question of changing thinking. The basic idea of converting HDU to a short circuit is to regard the matrix as a graph with n points in it, the outbound degree of point 1 is 1, the inbound degree of point N is 1, the outbound degree of other points is equal to the inbound degree, and the path length is not negative, it is equivalent to a path from node 1 to node N. Therefore, Xij = 1 indicates that edge passing (I, j) is required, and the cost is CIJ. Xij = 0 indicates no passing edge (I, j ). Note that CIJ is non-negative and the question requires the minimum total cost. Therefore, the optimal answer path must correspond to a simple path. In the end, we directly read the edge weight's Adjacent matrix and run the 1 to n shortest path. B: starting from 1, taking a ring (after at least one vertex, that is, it cannot be a self-ring) and returning to 1; Starting from N, take a ring (likewise) and return to n. That is, the outbound and inbound degrees of points 1 and N are both 1, and the outbound and inbound degrees of other points are 0. because the edge weight is not negative, the two rings correspond to two simple rings. Therefore, we can start from 1 and find a minimum cost loop with the cost of C1, and then start from N to find a minimum cost loop with the cost of C2. (You only need to add one more record when the shortest path algorithm updates the weight: if (I = s) CIR = min (CIR, dis [u] + G [u] [I]). Therefore, the final answer is Min (path, C1 + C2) */ /* BenProgramUse spfa to complete the shortest. However, the length of the closed-loop path starting from the starting point must be calculated. Therefore, we need to make some changes on the basis of common spfa. Set Dist [start] to INF. At the same time, the starting point is not to let the start point join, but to let the start point arrive. */ # Include <Stdio. h> # Include <Iostream> # Include < String . H> # Include <Algorithm> Using Namespace STD; Const Int INF =0x3f3f3f ; Const Int Maxn = 330 ; Int Cost [maxn] [maxn]; // Save the path length of the adjacent matrix Int Dist [maxn]; Int Que [maxn]; // Pay attention to the recycling of queues to build a cyclic queue Bool Vis [maxn];// Mark in queue Void Spfa ( Int Start, Int N ){ Int Front = 0 , Rear = 0 ; For ( Int V = 1 ; V <= N; V ++) // Initialization { If (V = start) // Because the closed loop of start is to be found, DIST [start] is set to INF and is not in the queue. {Dist [v] = INF; vis [v] = False ;} Else If (Cost [start] [v]! = INF) {Dist [v] = Cost [start] [v]; que [rear ++] =V; vis [v] = True ;} Else // That is, DIST [start] [v] = inf. This is not the case for this question. {Dist [v] = INF; vis [v] = False ;}} While (Front! = Rear) // Note that this condition is unequal because it is a cyclic queue. { Int U = que [Front ++ ]; For ( Int V = 1 ; V <= N; V ++ ){ If (Dist [v]> Dist [u] + Cost [u] [v]) {Dist [v] = DIST [u] + Cost [u] [v]; If (! Vis [v]) // Not in queue {Vis [v] = True ; Que [rear ++] = V; If (Rear> = maxn) rear = 0 ; // Cyclic queue }}} Vis [u] = False ; If (Front> = maxn) Front = 0 ;}} Int Main (){ // Freopen ("in.txt", "r", stdin ); // Freopen ("out.txt", "W", stdout ); Int N; While (Scanf ( " % D " , & N )! = EOF ){ For (Int I = 1 ; I <= N; I ++ ) For ( Int J = 1 ; J <= N; j ++ ) Scanf ( " % D " ,& Cost [I] [J]); spfa ( 1 , N ); Int Ans = DIST [N];// The shortest path from 1 to n Int Loop1 = DIST [ 1 ]; // 1 Closed Loop Length Spfa (N, N ); Int Loopn = DIST [N]; // N Closed Loop Length Ans = min (ANS, loop1 + Loopn); printf ( " % D \ n " , ANS );} Return 0 ;}
The following figure shows the spfa implemented by stack.
/* Using a stack to implement spfa is sometimes faster than a queue */ # Include <Stdio. h> # Include <Iostream> # Include < String . H> # Include <Algorithm> Using Namespace STD; Const Int Maxn = 330 ; Const Int INF = 0x3f3f3f ; Int Cost [maxn] [maxn]; Int Dist [maxn]; Int Q [maxn]; Bool Vis [maxn]; Void Spfa ( Int Start, Int N ){ // Stack implementation, sometimes faster than queue Int Top = 0 ; For ( Int V = 1 ; V <= N; V ++ ){ If (V =Start) {Dist [v] = INF; vis [v] = False ;} Else {Dist [v] = Cost [start] [v]; vis [v] = True ; Q [Top ++] = V ;}} While (Top! = 0 ){ Int U = Q [-- Top]; For ( Int V = 1 ; V <= N; V ++ ){ If (Dist [v]> Dist [u] + Cost [u] [v]) {Dist [v] = DIST [u] + Cost [u] [v]; If (! Vis [v]) {vis [v] = True ; Q [Top ++] = V ;}} vis [u] = False ;}} Int Main (){ // Freopen ("in.txt", "r", stdin ); // Freopen ("out.txt", "W", stdout ); Int N; While (Scanf ( " % D " , & N )! = EOF ){ For ( Int I = 1 ; I <= N; I ++ ) For ( Int J = 1 ; J <= N; j ++ ) Scanf ( " % D " ,&Cost [I] [J]); spfa ( 1 , N ); Int Ans = DIST [N]; // The shortest path from 1 to n Int Loop1 = DIST [ 1 ]; // 1 Closed Loop Length Spfa (N, N ); Int Loopn = DIST [N]; // N Closed Loop Length Ans = min (ANS, loop1 +Loopn); printf ( " % D \ n " , ANS );} Return 0 ;}