Bzoj 1001 the maximum flow of a rabbit captured by a wolf (dual diagram + Shortest Path), bzoj1001
Recommended article: Analysis of the application of the maximum and minimum theorem in the competition of informatics -- Zhou Dong
The question is now the favorite "Pleasant goat and the Big Wolf" of the children. It is said that the big wolf cannot catch the sheep, but it is good to catch the rabbit, and the rabbits are still stupid. They only have two nests, now you are the wolf king, facing the terrain of the following grid: the point in the upper left corner is (), and the point in the lower right corner is (N, M) (medium N = 4, M = 5 ). there are three types of roads: (x, y) <==> (x + 1, y) 2 :( x, y) <==> (x, y + 1) 3: (x, y) <=> (x + 1, y + 1) the weights on the road indicate the maximum number of rabbits that can pass through the road, and the road is undirected. the upper left corner and lower right corner are the rabbit's two nests. At the beginning, all the rabbits are gathered in the upper left corner (). Now they are going to the lower right corner (N, M) of the nest, wolf began to ambush the rabbits. of course, for the sake of insurance, if the number of rabbits allowed to pass a road is K, the wolf king needs to arrange the same number of K wolves to completely block the road, you need to help the wolf king arrange an ambush scheme so that the number of involved wolves is minimized while the rabbit is exhausted. Because the wolf is still in trouble looking for pleasant goat. input first act N, M. the size of the Grid. N and M are smaller than or equal to 1000. the next part is divided into N rows in the first part, the number of M-1 in each row, indicating the weight of the horizontal road. the second part of the total N-1 line, each line M number, indicating the right of the longitudinal road. the third part of the total N-1 line, the number of M-1 per line, indicating the weight of oblique Road. the input file must not exceed 10 moutput to output an integer, indicating the minimum number of wolves involved in the ambush. sample Input3 45 6 44 3 17 5 35 6 7 88 7 6 55 5 56 6 6 Sample Output14View Code question Image
Before talking about this part, please read the above article (excellent lecture %) (of course, just read 27 pages)
After reading this question, we can use its dual diagram to run the shortest path.
Source image dual chart
Number of faces x number of faces y
Point y, points x in the dual graph
Number of edges z
The number of faces is the opposite of the number of points.
Connect the start point and end point of the source image to create a new surface (this is required ).
Of course, there is no edge between s and t.
There is an edge between s and.
T and 2, 4, 6, and 12 have edges.
The dual graph we have built is numbered from left to right. The numbers in the dual graph are read in the order of horizontal, vertical, and oblique edges, therefore, we must number these images according to certain methods.
I use numbers from left to right, because we can clearly know the location of the two points connected by the current edge (two sides in the source image), because this is a plan, therefore, we can use the Euler's formula to determine the number of vertices (
In the source image ). The position of this vertex (the surface in the source image (three important times) in the current row is its number.
As long as an edge exists between two faces in the source image, the two vertices in its dual graph have an edge.
# Include <stdio. h> # include <string. h ># include <algorithm> using namespace std; int cnt, I, j, x, xx, xxx, h, t, s, hh [2010000], n, m, w; bool dd [2010000]; int e, l [2010000], d [1010000], hhh, ww; struct node {int v, next, z ;} B [6010000]; inline void add (int aa, int bb, int cc) // create a bidirectional edge {B [++ cnt]. v = bb; B [cnt]. next = hh [aa]; B [cnt]. z = cc; hh [aa] = cnt; B [++ cnt]. v = aa; B [cnt]. next = hh [bb]; B [cnt]. z = cc; hh [bb] = cnt;} void add1 () {for (I = 1; I <m; ++ I) {scanf ("% d ", & x); add (I * 2, t, x) ;}for (I = 2; I <n; ++ I) {for (j = 1; j <m; ++ j) {scanf ("% d", & x); add (I-1) * (m-1) * 2 + j * 2, (I-1) * (m-1) * 2 + j * 2-m * 2 + 1, x ); // use the Euler's formula to determine the number and create an edge (as is the add function below)} for (j = 1; j <m; ++ j) {scanf ("% d", & x); add (s, (n-2) * 2 * (m-1) + j * 2-1, x) ;}} void add2 () {for (I = 1; I <n; ++ I) {scanf ("% d", & x ); xx = (I-1) * (m-1) * 2 + 1; add (s, xx, x); for (j = 2; j <m; ++ j) {scanf ("% d", & x); xx + = 2; add (xx-1, xx, x);} scanf ("% d ", & x); add (xx + 1, t, x) ;}} inline void add3 () {for (I = 1; I <n; ++ I) {for (j = 1; j <m; ++ j) {scanf ("% d", & x); add (I-1) * (m-1) * 2 + j * 2, (I-1) * (m-1) * 2 + j * 2-1, x );}}}
// The following spfa must use cyclic queues to save space. If you don't need to use it, the space will be small (this is likely to be 1 million points after all. Void spfa () {dd [s] = true; h = 0; w = 0; memset (l, 0x3f, sizeof (l); // assign the l Array to the maximum value
// Hhh records the number of elements in the queue (in fact)
// The ww records several elements in the queue: l [s] = 0; while (1) {if (hhh> ww) break; h = hhh % 1000001; w = ww % 1000001; for (I = hh [s]; I = B [I]. next) {e = B [I]. v; if (l [s] + B [I]. z <l [e]) {l [e] = l [s] + B [I]. z; if (! Dd [e]) w = ww % 1000000, d [++ w] = e, ww ++, dd [e] = true ;}} dd [s] = false; h = hhh % 1000000; s = d [++ h]; hhh ++ ;}} int main () {scanf ("% d", & n, & m); if (n = m & n = 1) // special sentence {printf ("0"); return 0 ;}s = 0; t = 2 * (n-1) * (m-1) + 1; add1 (); // read the horizontal edge add2 (); // read the vertical edge add3 (); // read the oblique side spfa (); // evaluate the dual diagram of s ---- t printf ("% d", l [t]); return 0 ;}