1. 程式人生 > >【BZOJ】4643 卡常大水題【bitset優化bfs】

【BZOJ】4643 卡常大水題【bitset優化bfs】

題目連結:卡常大水題

#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 ; }