【BZOJ】4643 卡常大水題【bitset優化bfs】
阿新 • • 發佈:2019-01-05
題目連結:卡常大水題
#include <bits/stdc++.h>
using namespace std ;
typedef long long LL ;
typedef pair < int , int > pii ;
typedef unsigned int UI ;
#define clr( a , x ) memset ( a , x , sizeof a )
const int MAXN = 155 ;
const int BLOCK = 5 ;
struct Node {
int x , y , i , j ;
bool operator < ( const Node& a ) const {
return x != a.x ? x < a.x : y < a.y ;
}
} ;
struct Bitset {
UI c[BLOCK] ;
bool none () {
for ( int i = 0 ; i < BLOCK ; ++ i ) {
if ( c[i] ) return 0 ;
}
return 1 ;
}
void set () {
for ( int i = 0 ; i < BLOCK ; ++ i ) {
c[i] = ~0U ;
}
}
void reset () {
for ( int i = 0 ; i < BLOCK ; ++ i ) {
c[i] = 0 ;
}
}
void flip ( int x ) {
c[x >> 5] ^= 1U << ( x & 31 ) ;
}
UI& operator [] ( const int index ) {
return c[index] ;
}
} ;
Node a[MAXN * MAXN] ;
Bitset V1[MAXN] , V2[MAXN] , vis ;
UI pos[MAXN] , val[MAXN] ;
int n , m , LIM ;
int bfs ( Bitset G[MAXN] ) {
vis.set () ;
vis.flip ( 0 ) ;
queue < int > Q ;
Q.push ( 0 ) ;
while ( !Q.empty () ) {
int u = Q.front () ;
Q.pop () ;
for ( int i = 0 ; i < LIM ; ++ i ) {
for ( UI j = G[u][i] & vis[i] ; j ; j -= j & -j ) {
int v = __builtin_ctz ( j ) ;
vis[i] ^= 1U << v ;
Q.push ( i << 5 | v ) ;
}
}
}
for ( int i = 0 ; i < n ; ++ i ) {
if ( vis[pos[i]] & val[i] ) return 0 ;
}
return 1 ;
}
void solve () {
LIM = ( n - 1 ) / 32 + 1 ;
m = 0 ;
for ( int i = 0 ; i < n ; ++ i ) {
V1[i].reset () ;
V2[i].reset () ;
pos[i] = i / 32 ;
val[i] = 1U << ( i % 32 ) ;
for ( int j = 0 ; j < n ; ++ j , ++ m ) {
scanf ( "%d" , &a[m].x ) ;
a[m].i = i ;
a[m].j = j ;
}
}
m = 0 ;
for ( int i = 0 ; i < n ; ++ i ) {
for ( int j = 0 ; j < n ; ++ j , ++ m ) {
scanf ( "%d" , &a[m].y ) ;
}
}
sort ( a , a + m ) ;
int ans = INT_MAX ;
priority_queue < pii > q ;
for ( int i = 0 ; i < m ; ++ i ) {
V1[a[i].i].flip ( a[i].j ) ;
V2[a[i].j].flip ( a[i].i ) ;
q.push ( pii ( a[i].y , i ) ) ;
while ( !q.empty () ) {
int t = q.top ().second ;
V1[a[t].i].flip ( a[t].j ) ;
V2[a[t].j].flip ( a[t].i ) ;
if ( !bfs ( V1 ) || !bfs ( V2 ) ) {
V1[a[t].i].flip ( a[t].j ) ;
V2[a[t].j].flip ( a[t].i ) ;
break ;
}
q.pop () ;
ans = min ( ans , a[i].x + q.top ().first ) ;
}
}
printf ( "%d\n" , ans ) ;
}
int main () {
//freopen ( "inputf.in" , "r" , stdin ) ;
while ( ~scanf ( "%d" , &n ) ) solve () ;
//printf ( "%.3f\n" , 1.0 * clock () / CLOCKS_PER_SEC ) ;
return 0 ;
}