Cod sursa(job #1733014)

Utilizator xtreme77Patrick Sava xtreme77 Data 23 iulie 2016 14:44:31
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.7 kb
/**
 * Code by Patrick Sava
 * "Spiru Haret" National College of Bucharest
 **/

# include "fstream"
# include "cstring"
# include "vector"
# include "queue"
# include "bitset"
# include "algorithm"
# include "map"
# include "set"
# include "unordered_map"
# include "deque"
# include "string"
# include "iomanip"
# include "cmath"
# include "stack"
# include "cassert"

const char IN [ ] =  "ubuntzei.in" ;
const char OUT [ ] = "ubuntzei.out" ;

using namespace std ;

# define pb push_back
# define mp make_pair
# define FORN( a , b , c ) for ( register int a = b ; a <= c ; ++ a )
# define FORNBACK( a , b , c ) for ( register int a = b ; a >= c ; -- a )

ifstream cin ( IN ) ;
ofstream cout ( OUT ) ;

const int MAX = 2014 ;
const int UB = 16 ;

struct cmp {
    bool operator ( ) ( const pair < int , int > &a , const pair < int , int > &b ) const
    {
        return a.second > b.second ;
    }
};

priority_queue < pair < int , int > , vector < pair < int , int > > , cmp > H ;
int n ;

vector < pair < int , int > > gr [ MAX ] ;

void dijkstra ( int cur , int save [ ] )
{
    H.push ( mp ( cur , 0 ) ) ;
    FORN ( i , 1 , n ) {
        save [ i ] = 1000000014 ;
    }
    save [ cur ] = 0 ;
    while ( H.empty() == 0 )
    {
        int nod = H.top().first ;
        int cost = H.top().second ;
        H.pop() ;

        if ( cost != save [ nod ] ) {
            continue ;
        }

        for ( auto x : gr [ nod ] ) {

            if ( save [ x.first ] > save [ nod ] + x.second ) {
                save [ x.first ] = save [ nod ] + x.second ;
                H.push ( mp ( x.first , save [ x.first ] ) ) ;
            }
        }
    }
}

int ubu [ UB ] ;
int ONE [ MAX ] ;

int dijkubu [ UB ] [ MAX ] ;
int dp [ 1 << UB ] [ UB ] ;

int main()
{
    int m ;
    cin >> n >> m ;
    int k ;
    cin >> k ;
    FORN ( i , 0 , k - 1 ) {
        cin >> ubu [ i ] ;
    }
    while ( m -- ) {
        int x , y , cost ;
        cin >> x >> y >> cost ;
        gr [ x ].pb ( mp ( y , cost ) ) ;
        gr [ y ].pb ( mp ( x , cost ) ) ;
    }
    dijkstra( 1 , ONE ) ;
    if ( k == 0 ) {
        cout << ONE [ n ] << '\n' ;
        return 0 ;
    }
    FORN ( i , 0 , k - 1 ) {
        dijkstra( ubu [ i ] , dijkubu [ i ] ) ;
    }
    int masca = 1 << k ;
    masca -- ;
    FORN ( i , 1 , masca ) {
        FORN ( j , 0 , k - 1 ) {
            dp [ i ] [ j ] = 1 << 30 ;
        }
    }
    FORN ( i , 1 , masca ) {
        //int caz_particular = 0 ;
        FORN ( j , 0 , k ) {
            if ( i == ( 1 << j ) ) {
                dp [ i ] [ j ] = ONE [ ubu [ j ] ] ;
                //caz_particular = 1 ;
                break ;
            }
        }
        /*if ( caz_particular ) {
            continue ;
        }
        FORN ( j , 0 , k ) {
            if ( i & ( 1 << j ) ) {
                FORN ( r , 0 , k ) {
                    if ( r != j and ( i & ( 1 << r ) ) ) {
                        int aux = dp [ i - ( 1 << j ) ] [ r ] + dijkubu [ r ] [ ubu [ j ] ] ;
                        dp [ i ] [ j ] = min ( dp [ i ] [ j ] , aux ) ;
                    }
                }
            }
        }*/
        FORN ( j , 0 , k ) {
            if ( i & ( 1 << j ) ) {
                FORN ( r , 0 , k ) {
                    if ( ( i & ( 1 << r ) ) == 0 ) {
                        dp [ i ^ ( 1 << r ) ] [ r ] = dp [ i ] [ j ] + dijkubu [ j ] [ ubu [ r ] ] ;
                    }
                }
            }
        }
    }
    int best = 1 << 30 ;
    FORN ( i , 0 , k - 1 ) {
        best = min ( best , dp [ masca ] [ i ] + dijkubu [ i ] [ n ] ) ;
    }
    cout << best << '\n' ;
    return 0;
}