【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 ;
}
發佈了718 篇原創文章 · 獲贊 37 · 訪問量 64萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章