Pourquoi sur le graphe de capacités suivantes :
J’obtiens un flot max à 13 :
o
Alors qu’il en existe un à 22 :
J’ai l’impression que c’est parce qu’il existe un chemin augmentant qui emprunte l’arête inverse t1 <- 0
. Mais du coup, faut-il considérer une « capacité négative » sur cet arc ? Est-ce que ça a du sens ?
Voici le code, B.cpp :
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std ;
#define SIZE 2 * 100 + 4
#define INF 1e9
int n , m ;
bool visit [ SIZE ];
vector < int > graph [ SIZE ];
unordered_map < int , int > capacity , flow ;
int c = 0 ;
bool augment ( int u , int val ) {
c ++ ;
// cout << "-> " << u << " " << val << endl;
visit [ u ] = true ;
if ( u == 2 * n + 3 )
return val ;
int v , res , delta , cuv ;
for ( int i = 0 ; i < graph [ u ]. size (); ++ i ) {
v = graph [ u ][ i ];
cuv = capacity [ u * SIZE + v ];
if ( ! visit [ v ] && cuv > flow [ u * SIZE + v ]) {
res = min ( val , cuv - flow [ u * SIZE + v ]);
delta = augment ( v , res );
if ( delta > 0 ) {
flow [ u * SIZE + v ] += delta ;
flow [ v * SIZE + u ] -= delta ;
return delta ;
}
}
}
return 0 ;
}
void graphviz () {
cout << "digraph G {" << endl << "rankdir=LR;" << endl ;
int v ;
for ( int u = 0 ; u < 2 * n + 4 ; ++ u ) {
for ( int i = 0 ; i < graph [ u ]. size (); ++ i ) {
v = graph [ u ][ i ];
cout << u << " -> " << v << "[label=" << flow [ u * SIZE + v ] << "];" << endl ;
}
}
cout << "}" << endl ;
}
void add ( int u , int v , int c ) {
graph [ u ]. push_back ( v );
flow [ u * SIZE + v ] = 0 ;
flow [ v * SIZE + u ] = 0 ;
capacity [ u * SIZE + v ] = c ;
}
int main () {
int nbTests ;
int clean [ 100 ][ 100 ];
int a [ 100 ], b [ 100 ], s [ 100 ];
cin >> nbTests ;
for ( int t = 1 ; t <= nbTests ; ++ t ) {
cin >> n >> m ;
for ( int i = 0 ; i < n ; ++ i )
cin >> a [ i ] >> b [ i ] >> s [ i ];
for ( int i = 0 ; i < n ; ++ i )
for ( int j = 0 ; j < n ; ++ j )
cin >> clean [ i ][ j ];
int s1 = 2 * n , t1 = 2 * n + 1 , s2 = 2 * n + 2 , t2 = 2 * n + 3 ;
for ( int i = 0 ; i <= t2 ; ++ i )
graph [ i ]. clear ();
for ( int i = 0 ; i < n ; ++ i ) {
// cout << i << ": " << s[i] << " " << ceil(s[i] / m) << endl;
add ( s1 , i , ceil ( s [ i ] / m ));
add ( i , t1 , INF );
add ( s2 , n + i , INF );
add ( n + i , t2 , ceil ( s [ i ] / m ));
}
for ( int i = 0 ; i < n ; ++ i )
for ( int j = 0 ; j < n ; ++ j )
if ( b [ i ] + clean [ i ][ j ] <= a [ j ])
add ( i , n + j , INF );
add ( t1 , s2 , 9 );
if ( t == 2 ) {
do {
for ( int i = 0 ; i <= t2 ; ++ i )
visit [ i ] = false ;
} while ( augment ( s1 , 1e9 ) > 0 );
graphviz ();
}
}
// graphviz();
/* int d = 1;
for(int i = 0; i < n; ++i) {
if(flow[2 * n * SIZE + i] < 1) {
cout << "NO" << endl;
// cout << c << " " << d << endl;
return 0;
}
}
cout << "YES" << endl;
cout << c << " " << d << endl; */
return 0 ;
}
Sur l’entrée suivante, B.in :
1
4 1
1 100 10
50 130 3
150 200 15
80 170 7
0 2 3 4
5 0 7 8
9 10 0 12
13 14 15 0
Commentaires