Cod sursa(job #1326274)

Utilizator nimicLeoveanu Mihaita Alexandru nimic Data 25 ianuarie 2015 00:15:30
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <fstream>
#include <vector>
#include <queue>
const int MAX = 2014 ;
const int KAPPA = 15 ;
 
#define pb push_back
#define mp make_pair
 
using namespace std ;
 
typedef pair < int , int > P ;
 
ifstream in ("ubuntzei.in" ) ;
ofstream out ("ubuntzei.out") ;
 
vector < P > gr [ MAX ] ;
 
int dinunu [ MAX ] ;
 
int mat [ KAPPA ] [ MAX ] ;
 
int dp [ 1 << KAPPA ] [ KAPPA ] , nod [ KAPPA ] ;
 
struct cmp {
    bool operator ( ) ( const P &a , const P &b ) const {
        return ( a.second > b.second ) ;
    }
};
 
priority_queue < P , vector < P > , cmp > h ;
 
void dijkstra ( int nod , int *d )
{
    h.push ( mp ( nod , 0 ) ) ;
    for ( int i = 1 ; i <= 2000 ; ++ i )
        d [ i ] = 1 << 30 ;
    d [ 1 ] = 0 ;
    while ( !h.empty( ) )
    {
        int fata = h.top ( ).first ;
        int cost = h.top ( ).second ;
        h.pop ( ) ;
        for ( auto x : gr [ fata ] )
            if ( x.second + cost < d [ x.first ] )
            {
                d [ x.first ] = x.second + cost ;
                h.push ( mp ( x.first , d [ x.first ] ) ) ;
            }
    }
}
 
int main (      )
{
    int n , m , k ;
    in >> n >> m >> k ;
    for ( int i = 0 ; i < k ; ++ i )
        in >> nod [ i ] ;
    for ( ; m ; -- m )
    {
        int x , y , cost ;
        in >> x >> y >> cost ;
        gr [ x ].pb ( mp ( y , cost ) ) ;
        gr [ y ].pb ( mp ( x , cost ) ) ;
        //fout << x << ' ' << y << ' ' << cost << endl ;
    }
    dijkstra( 1 , dinunu ) ;
    if ( k == 0 )
    {
        out << dinunu [ n ] << '\n' ;
        return 0 ;
    }
    for ( int i = 0 ; i < k ; ++ i )
        dijkstra ( nod [ i ] , mat [ i ] ) ;
 
    for ( int i = 1 ; i < ( 1 << k ) ; ++ i )
    {
        int ok = 0 ;
        for ( int j = 0 ; j < k ; ++ j )
            if ( i == ( 1ll << j ) ){
                dp [ i ] [ j ] = dinunu [ nod [ j ] ] ;
                ok = 1 ;
                break ;
            }
        if ( ok )
            continue ;
        for ( int j = 0 ; j < k ; ++ j )
        {
            dp [ i ] [ j ] = 1ll << 30 ;
            if ( i & ( 1ll << j ) )
            {
                for ( int r = 0 ; r < k ; ++ r )
                {
                    if ( r != j && ( i & ( 1ll << r ) ) )
                    {
                        int aux = dp [ i - ( 1ll << j ) ] [ r ] + mat [ r ] [ nod [ j ] ] ;
                        dp [ i ] [ j ] = min ( dp [ i ] [ j ] , aux ) ;
                    }
                }
            }
        }
    }
 
    int rasp = 1 << 30 ;
    for ( int i = 0 ; i < k ; ++ i )
        rasp = min ( rasp , dp [ - 1 + ( 1ll << k ) ] [ i ] + mat [ i ] [ n ] ) ;
 
    out<<rasp<<'\n';
    return 0;
}