BZOJ-2007: [Noi2010]海拔(平面最小割转对偶图最短路)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2007

机房快关了。。。贴了代码就滚回去了。。。

代码:

#include 
#include 
#include 
#include 
 
using namespace std ;
 
#define MAXN 510
#define inf 0x7fffffff
#define MAXV MAXN * MAXN
 
struct edge {
    edge *next ;
    int t , d ;
} *head[ MAXV ] ;
 
void AddEdge( int s , int t , int d ) {
    edge *p = new( edge ) ;
    p -> t = t , p -> d = d , p -> next = head[ s ] ;
    head[ s ] = p ;
}
 
int node[ MAXN ][ MAXN ] , S , T , n , V = 0 ;
 
int dist[ MAXV ] ; bool f[ MAXV ] ;
 
struct cmp {
    bool operator(  )( int x ,int y ) {
        return dist[ x ] > dist[ y ] ;
    }
};
 
priority_queue< int , vector< int > , cmp >Q ;
 
int spfa(  ) {
    for ( int i = 0 ; i ++ < V ; ) dist[ i ] = inf , f[ i ] = true ;
    Q.push( S ) , dist[ S ] = 0 ;
    while ( ! Q.empty(  ) ) {
        int v = Q.top(  ) ; Q.pop(  ) ;
        if ( v == T || dist[ v ] > dist[ T ] ) return dist[ T ] ;
        if ( ! f[ v ] ) continue ; f[ v ] = false ;
        for ( edge *p = head[ v ] ; p ; p = p -> next ) if ( dist[ p -> t ] > dist[ v ] + p -> d ) {
            dist[ p -> t ] = dist[ v ] + p -> d ; f[ p -> t ] = true ; Q.push( p -> t ) ;
        }
    }
    return dist[ T ] ;
}
 
int main(  ) {
    scanf( "%d" , &n ) ;
    S = ++ V , T = ++ V ;
    for ( int i = 0 ; i ++ < n ; ) for ( int j = 0 ; j ++ < n ; ) node[ i ][ j ] = ++ V ;
    for ( int i = 0 ; i ++ < n ; ) {
        int x ; scanf( "%d" , &x ) ;
        AddEdge( node[ 1 ][ i ] , T , x ) ;
    }
    for ( int i = 0 ; i ++ < n - 1 ; ) {
        for ( int j = 0 ; j ++ < n ; ) {
            int x ; scanf( "%d" , &x ) ;
            AddEdge( node[ i + 1 ][ j ] , node[ i ][ j ] , x ) ;
        }
    }
    for ( int i = 0 ; i ++ < n ; ) {
        int x ; scanf( "%d" , &x ) ;
        AddEdge( S , node[ n ][ i ] , x ) ;
    }
    for ( int i = 0 ; i++ < n ; ) {
        int x ; scanf( "%d" , &x ) ; AddEdge( S , node[ i ][ 1 ] , x ) ;
        for ( int j = 0 ; j ++ < n - 1 ; ) scanf( "%d" , &x ) , AddEdge( node[ i ][ j ] , node[ i ][ j + 1 ] , x ) ;
        scanf( "%d" , &x ) ; AddEdge( node[ i ][ n ] , T , x ) ;
    }
    for ( int i = 0 ; i ++ < n ; ) {
        int x ; scanf( "%d" , &x ) ; 
    }
    for ( int i = 0 ; i ++ < n - 1 ; ) for ( int j = 0 ; j ++ < n ; ) {
        int x ; scanf( "%d" , &x ) ; AddEdge( node[ i ][ j ] , node[ i + 1 ][ j ] , x ) ;
    }
    for ( int i = 0 ; i ++ < n ; ) {
        int x ; scanf( "%d" , &x ) ;
    }
    for ( int i = 0 ; i ++ < n ; ) {
        int x ; scanf( "%d" , &x ) ; 
        for ( int j = 0 ; j ++ < n - 1 ; ) scanf( "%d" , &x ) , AddEdge( node[ i ][ j + 1 ] , node[ i ][ j ] , x ) ;
        scanf( "%d" , &x ) ;
    }
    printf( "%d\n" , spfa(  ) ) ;
    return 0 ;
}

你可能感兴趣的:(BZOJ-2007: [Noi2010]海拔(平面最小割转对偶图最短路))