Cod sursa(job #1477678)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 26 august 2015 18:31:02
Problema Ubuntzei Scor 45
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.74 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
#include <bitset>
 
const int MAX_K = 15;
const int MAX_N = 2000;
const int INF = 2000000000;
const char IN [ ] = "ubuntzei.in" ;
const char OUT[ ] = "ubuntzei.out" ;
 
using namespace std;
 
ifstream cin ( IN );
ofstream cout( OUT );
 
int cost [ MAX_N ][ ( 1 << ( MAX_K + 1 ) ) ];
 
int pos [ MAX_K + 1 ];
 
bitset < ( 1 << ( MAX_K + 1 ) ) > seen [ MAX_N + 1 ];
 
vector < pair < int, int > > adj [ MAX_N + 1 ];
 
int n, k;
 
struct cmp {
    bool operator () ( const pair < int, int > &a, const pair < int, int > &b ) const
    {
        return cost [ a.first ][ a.second ] > cost [ b.first ][ b.second ];
    }
};
 
priority_queue < pair < int, int >, vector < pair < int, int > >, cmp > Q;
 
inline int getPos ( int node )
{
    int lo = 0, hi = k + 1, mid;
 
    while ( hi - lo > 1 )
    {
        mid = ( lo + hi ) / 2;
        if ( pos [ mid ] <= node )
            lo = mid;
        else
            hi = mid;
    }
    return pos [ lo ] == node ? lo : 0;
}
 
inline int dijkstra ( int node )
{
    for ( int i = 2; i <= n; i ++ )
        for ( int j = 0; j < ( 1 << ( k + 1 ) ); j ++ )
            cost [ i ][ j ] = INF;
 
    pair < int, int > curr;
    int ans = INF;
 
    Q.push ( make_pair ( node, ( 1 << getPos ( node ) ) ) );
    do
    {
        curr = Q.top ( );
        Q.pop ( );
 
        if ( seen [ curr.first ][ curr.second ] ) continue;

        if ( curr.first == n )
        {
            if ( ( curr.second | 1 ) == ( 1 << ( k + 1 ) ) - 1 )
            {
                ans = min ( ans, cost [ curr.first ][ curr.second ] );
            }
            continue;
        }

	seen [ curr.first ][ curr.second ] = 1;

        for ( auto u : adj [ curr.first ] )
        {
            int son = u.first;
            int costEdge = u.second;
            int bitMask = curr.second | ( 1 << getPos ( son ) );
            if ( cost [ son ][ bitMask ] > cost [ curr.first ][ curr.second ] + costEdge )
            {
                cost [ son ][ bitMask ] = cost [ curr.first ][ curr.second ] + costEdge;
                Q.push ( make_pair ( son, bitMask ) );
            }
        }
    } while ( !Q.empty( ) );
    return ans;
}
 
int main ( void )
{
    int m;
    int u, v, cost;
 
    cin >> n >> m >> k;
 
    for ( int i = 1; i <= k; i ++ ) cin >> pos [ i ];
 
    sort ( pos + 1, pos + k + 1 );
 
    for ( int i = 1; i <= m; i ++ )
    {
        cin >> u >> v >> cost;
        adj [ u ].emplace_back ( make_pair ( v, cost ) );
        adj [ v ].emplace_back ( make_pair ( u, cost ) );
    }
    cin.close ( );
 
    cout << dijkstra ( 1 ) << '\n';
    cout.close ( );
    return 0;
}