Network flow 24 question Luogu 4016 Load balancing problem

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 }
Years

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325353921&siteId=291194637