Cod sursa(job #2481676)

Utilizator Anakin1001George Giorgiu Gica Anakin1001 Data 27 octombrie 2019 11:36:39
Problema Ubuntzei Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.58 kb
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
#include <cstring>

#define NODES 2000 + 1
#define inf INT_MAX
#define FOR(i, a, b) for( i = a; i <= b; i++ )

using namespace std;

ifstream f ( "ubuntzei.in" );
ofstream g ( "ubuntzei.out" );

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

vector < pair < int, int > > graph[NODES];
priority_queue < pair < int, int >, vector < pair < int, int > >, cmp > heap;

int v[17], d[17][NODES], dp[16][ ( 1 << 15 ) + 1 ];
bool viz[NODES];

int main()
{   int n, m, k, x, y, cost, i, node, st, new_node;
    f >> n >> m >> k;
    FOR( i, 1, k )
        f >> v[i];
    FOR( i, 1, m ){
        f >> x >> y >> cost;
        graph[x].push_back ( {y, cost} );
        graph[y].push_back ( {x, cost} );
    }
    v[ ++k ] = 1;
    FOR( i, 1, k ){
        for ( int j = 1; j <= n; j++ )
            if ( j != v[i] )
                d[i][j] = inf;
        memset ( viz, 0, sizeof ( viz ) );
        heap.push( {v[i], 0} );
        while ( !heap.empty() ){
            if ( viz[heap.top().first] == 1 ){
                heap.pop();
                continue;
            }
            int node = heap.top().first;
            int cost = heap.top().second;
            for ( int j = 0; j < graph[node].size(); j++ ){
                int new_node = graph[node][j].first;
                int new_cost = graph[node][j].second;
                if ( d[i][new_node] > cost + new_cost ){
                    d[i][new_node] = cost + new_cost;
                    heap.push ( {new_node, cost + new_cost} );
                    viz[new_node] = 0;
                }
            }
            viz[node] = 1;
        }
    }
    if ( k == 1 ){
        g << d[1][n];
        g.flush();
        return 0;
    }
    k--;
    int N = ( 1 << k ) - 1;
    FOR( i, 1, k )
        FOR( st, 1, N );
            dp[i][st] = inf;
    FOR( i, 1, k )
        dp[i][ 1 << (i - 1) ] = d[i][1];
    FOR( st, 1, N )
        FOR( node, 1, k )
            if ( dp[node][st] != inf )
                FOR( new_node, 1, k )
                    if ( new_node != node && ( st >> ( new_node - 1 ) & 1 == 0 ) ){
                        int stare = ( st | ( 1 << ( new_node - 1 ) ) );
                        dp[new_node][stare] = min ( dp[new_node][stare], dp[node][st] + d[node][ v[new_node] ] );
                    }
    int S = INT_MAX;
    FOR(node, 1, k )
        S = min ( S, dp[node][N] + d[node][n] );
    g << S;
    g.flush();
    return 0;
}