Rebuilding the map
The first intuition is that the introductory question is divided into cards, and that question is greedy.
But the network flow label is done with network flow.
Mapping: (traffic, cost)
1. Super source src + super sink sink
2. For warehouse i, split it into two points Ai and Bi
2.1. Establish (inf, 0) from Ai to Bi
2.2. Build edges from Bi to Ai-1 and Ai+1 (inf, 1)
3. Super source point and Ai edge (stock, 0)
4. Bi and super sinks build edges (avr, 0) -> (((avr means average)))
Correctness:
Since the cost flow follows the shortest path among the edges with traffic, the edge it "fills in" at the beginning must have a cost of 0 (if it has the ability to "fill in"), that is, src->Ai-> The edge on the Bi->sink path; but if some warehouses cannot "fill out" the flow of the mean edge, that is, the graph can still be expanded, then it must be shipped from other places, then the cost of 1 must be passed. Bi->Aj edge, which will incur costs. Since it is the shortest path of spfa, the currently obtained path must be the smallest transportation cost.
The condition for the termination of augmentation must be that all the traffic of avr is full, that is, the situation where each warehouse reaches the average value at the end; otherwise, it will continue to expand, which is equivalent to carrying it all the time!
Code:
1 // luogu-judger-enable-o2 2 //AC,不开o2也AC 3 #include <bits/stdc++.h> 4 5 const int N = 1000 + 5 ; 6 7 std :: queue < int > q ; 8 9 int head [ N ] , nxt [ N ] , dis [ N ] , flt [ N ] , to [ N ] , cn = 1 ; 10 int pree [ N ] , pred [ N ] , c [ N ] ; 11 int src , sink , inf , n , m , x , mincost , avr ; 12 bool vis [ N ] ; 13 14 void create ( int u, int v, int f, int d) { 15 cn++ ; 16 to [cn] = v; 17 dis[cn] = d; 18 flt[cn] = f; 19 nxt[cn] = head[u]; 20 head[u] = cn; 21 22 cn++ ; 23 to [cn] = u; 24 dis[cn] = -d; 25 flt [cn] = 0 ; 26 nxt [ cn ] = head [ v ] ; 27 head [ v ] = cn ; 28 } 29 30 void prp ( ) { 31 int o [ 5 ] ; 32 memset ( o , 127 , sizeof ( o ) ) ; 33 inf = o [ 0 ] ; 34 } 35 36 bool spfa ( ) { 37 memset ( vis , false , sizeof ( vis ) ) ; 38 memset ( c , 127 , sizeof ( c ) ) ; 39 q . push ( src ) ; 40 c [ src ] = 0 ; vis [ src ] = true ; 41 while ( ! q . empty ( ) ) { 42 int tmp = q . front ( ) , v ; 43 q . pop ( ) ; vis [ tmp ] = false ; 44 for ( int i = head [ tmp ] ; i ; i = nxt [ i ] ) { 45 v = to [ i ] ; 46 if ( flt [ i ] && c [ v ] > c [ tmp ] + dis [ i ] ) { 47 c [ v ] = c [ tmp ] + dis [ i ] ; 48 pree [ v ] = i ; 49 pred [ v ] = tmp ; 50 if ( ! vis [ v ] ) { 51 q . push ( v ) ; 52 vis [ v ] = true ; 53 } 54 } 55 } 56 } 57 return c [ sink ] < inf ; 58 } 59 60 void augment ( ) { 61 int u = sink, delta = inf; 62 while (u! = Src) ( 63 if ) (delta> flt [pree [u]]) 64 delta = flt [pree [u]]; 65 u = before [u]; 66 } 67 u = sink; 68 while (u! = Src) { 69 flt [pree [u]] - = delta; 70 flt [pree [u] ^ 1 ] + = delta; 71 u = before [u]; 72 } 73 mincost += delta * c [ sink ] ; 74 } 75 76 77 int main ( ) { 78 scanf ( "%d" , & n ) ; 79 prp ( ) ; 80 src = 0 ; sink = 2 * n + 1 ; 81 for ( int i = 1 ; i <= n ; i ++ ) { 82 scanf ( "%d" , & x ) ; 83 create ( src , i , x , 0 ) ; 84 avr += x ; 85 } 86 avr /= n ; 87 88 for ( int i = 1 ; i <= n ; i ++ ) 89 create ( i , i + n , inf , 0 ) ; 90 for ( int i = n + 2 ; i < 2 * n ; i ++ ) 91 create ( i , i - n - 1 , inf , 1 ) , create ( i , i - n + 1 , inf , 1 ) ; 92 create ( n + 1 , 2 , inf , 1 ) , create ( n + 1 , n , inf , 1 ) ; 93 create ( n + n , 1 , inf , 1 ) , create ( n + n , n - 1 , inf , 1 ) ; 94 95 for ( int i = n + 1 ; i <= n + n ; i ++ ) 96 create ( i , sink , avr , 0 ) ; 97 while ( spfa ( ) ) 98 augment ( ) ; 99 printf ( "%d" , mincost ) ; 100 return 0 ; 101 }