Cod sursa(job #2356053)

Utilizator Andrei-27Arhire Andrei Andrei-27 Data 26 februarie 2019 14:30:10
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.41 kb
#import<bits/stdc++.h>
#define pb push_back
#define mp make_pair
using namespace std;
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
const int oo = ( 1 << 30 ) ;
bool inq [ 2005 ] ;
vector < pair < int , int > > v [ 2005 ] ;
vector < int > d ( 2005 , oo ) ;
int n , m , k , st [ 2005 ] , cntk ;
int dist [ 18 ][ 18 ] ;
int dp [ 18 ][ ( 1 << 17 ) + 1 ] ;
struct cmp
{
    bool operator ()( int i , int j )
    {
        return d [ i ] > d [ j ] ;
    }

};

priority_queue < int , vector < int > , cmp > q;

void input()
{
    int x , y , z , i ;
    in >> n >> m ;
    in >> k ;
    st [ 0 ] = 1 ;
    for ( i = 1 ; i <= k ; ++ i ) in >> st [ i ] ;
    st [ ++ k ] = n ;
    while ( m -- )
    {
        in >> x >> y >> z ;
        v [ x ].pb( mp ( y , z ) ) ;
        v [ y ].pb( mp ( x , z ) ) ;
    }
}

void dijkstra ( int start )
{
    int nod , cost , vecin , i ;
    for ( i = 1 ; i <= n ; ++ i )   d [ i ] = oo ;
    q.push( st [ start ] ) ;
    d [ st [ start ] ] = 0 ;

    while ( !q.empty() )
    {
        nod = q.top() ;
        q.pop() ;

        inq [ nod ] = 0 ;
        for ( size_t i = 0 ; i < v [ nod ].size() ; ++ i )
        {

            vecin = v [ nod ][ i ].first ;
            cost = v [ nod ][ i ].second ;

            if ( cost + d[ nod ] < d [ vecin ] )
            {
                d [ vecin ] = cost + d [ nod ] ;
                if ( !inq [ vecin ] )   q.push( vecin ) ;
                inq [ vecin ] = 1 ;
            }
        }
    }
    for ( i = 0 ; i <= k ; ++ i )
        dist [ start ][ i ] = d [ st [ i ] ] ;
}

void smen ()
{
     int i , j , p , l , sol ;

    for ( i = 0 ; i <= k ; ++ i )
    for ( j = 0 ; j <= ( 1 << k ) ; ++ j )
    dp [ i ][ j ] = oo ;


    dp [ 0 ][ 1 ] = 0 ;


    l = ( 1 << k ) ;
    for ( int i = 1 ; i <= ( 1 << k ) - 1 ; i ++ )
    for ( int j = 0 ; j <= k ; j ++)
    if ( ( i & ( 1 << j ) ) != 0 )

        for ( int p = 0 ; p <= k ; ++ p )
        if ( ( i & ( 1 << p ) ) == 0 )

            dp [ p ][ i | ( 1 << p ) ] = min ( dist [ j ][ p ] + dp [ j ][ i ] , dp [ p ][ i | ( 1 << p ) ] ) ;


    sol = oo ;
    for ( i = 0 ; i <= k ; ++ i )
    {
        sol = min ( sol , dp [ i ][ l - 1 ] + dist [ i ][ k ]  ) ;
    }

    out << sol ;
}

int main ()
{
    int  i , j ;


    input() ;
      for ( i = 0 ; i <= k ; ++ i )
        dijkstra( i ) ;
    smen() ;

}