这题也太狗了,普通的dinic根本过不去
我加上了深度优化也还差一个点
#include <iostream>
#include <cstring>
#include <queue>
using namespace std ;
const int N = 205 ;
const double tps = 0.0000001 , INF = 1e7 ;
int n , s , t , vis[N] , dep[N] ;
double a[N][N] , b[N][N] , dis[N] , ans ;
int read ( ) {
char ch = getchar ( ) ;
int x = 0 ;
while ( ch < '0' || ch > '9' )
ch = getchar ( ) ;
while ( ch >= '0' && ch <= '9' )
x = x * 10 + ch - 48 , ch = getchar ( ) ;
return x ;
}
struct Edge {
int nxt , to , len ;
double dis ;
} edge[N*N] ;
int cnt , head[N] ;
void insert ( int u , int v , int w , double ww ) {
edge [ ++ cnt ] = Edge { head [ u ] , v , w , ww } ;
head [ u ] = cnt ;
edge [ ++ cnt ] = Edge { head [ v ] , u , 0 , -ww } ;
head [ v ] = cnt ;
}
queue < int > q ;
bool SPFA ( ) {
memset ( vis , 0 , sizeof ( vis ) ) ;
memset ( dep , 0 , sizeof ( dep ) ) ;
for ( int i = 1 ; i <= t ; ++ i )
dis [ i ] = - INF ;
dis [ s ] = 0 ;
dep [ s ] = 1 ;
q .push ( s ) ;
while ( ! q .empty ( ) ) {
int x = q .front ( ) ; q .pop ( ) ;
++ vis [ x ] ;
if ( vis [ x ] > n )
return false ;
for ( int i = head [ x ] ; i ; i = edge [ i ] .nxt ) {
int y = edge [ i ] .to ;
if ( dis [ y ] >= dis [ x ] + edge [ i ] .dis || ! edge [ i ] .len )
continue ;
dis [ y ] = dis [ x ] + edge [ i ] .dis ;
dep [ y ] = dep [ x ] + 1 ;
q .push ( y ) ;
}
}
return dis [ t ] != - INF ;
}
int dfs ( int x , int now ) {
if ( x == t )
return now ;
int res = now ;
for ( int i = head [ x ] ; i && res ; i = edge [ i ] .nxt ) {
int y = edge [ i ] .to ;
if ( dis [ y ] != dis [ x ] + edge [ i ] .dis || ! edge [ i ] .len || dep [ y ] != dep [ x ] + 1 )
continue ;
int w = dfs ( y , min ( res , edge [ i ] .len ) ) ;
edge [ i ] .len -= w ;
edge [ i ^ 1 ] .len += w ;
ans += w * edge [ i ] .dis ;
res -= w ;
}
return now - res ;
}
int main ( ) {
n = read ( ) ;
s = n + n + 1 , t = s + 1 ;
for ( int i = 1 ; i <= n ; ++ i )
for ( int j = 1 ; j <= n ; ++ j )
a [ i ] [ j ] = read ( ) ;
for ( int i = 1 ; i <= n ; ++ i )
for ( int j = 1 ; j <= n ; ++ j )
b [ i ] [ j ] = read ( ) ;
double l = 0 , r = 10000 , mid ;
while ( r - l > tps ) {
mid = ( l + r ) / 2 ;
cnt = 1 ;
for ( int i = 1 ; i <= n ; ++ i )
for ( int j = 1 ; j <= n ; ++ j )
insert ( i , n + j , 1 , a [ i ] [ j ] - mid * b [ i ] [ j ] ) ;
for ( int i = 1 ; i <= n ; ++ i )
insert ( s , i , 1 , 0 ) , insert ( n + i , t , 1 , 0 ) ;
ans = 0 ;
while ( SPFA ( ) )
dfs ( s , n ) ;
if ( ans >= 0 )
l = mid ;
else
r = mid ;
}
printf ( "%.6lf\n" , r ) ;
return 0 ;
}