Cod sursa(job #2564987)

Utilizator borscalinCalin-Stefan Georgescu borscalin Data 2 martie 2020 11:29:45
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.29 kb
#include <fstream>
#include <queue>
#include <iostream>

std::ifstream fin ( "ubuntzei.in" );
std::ofstream fout ( "ubuntzei.out" );

const int NMAX = 18;
int INF = 1<<30;

struct Node {
    int node;
    int cost;
};

int dist[1 + NMAX];
bool viz[1 + NMAX];
std::vector <int> dest;
std::vector <Node> edges[1 + NMAX];
int cost[1 + NMAX][1 + NMAX];
int sol[1 + ( 1<< NMAX ) ][1 + NMAX];
int N, M, K;

class CMP {
    public : bool operator () ( int a, int b ) const {
        return dist[a] > dist[b];
    }
};

std::priority_queue < int, std::vector <int>, CMP > q;

void dijkstra ( int start ) {
    q.push ( start ); 
    dist[start] = 0;
    while ( !q.empty() ) {
        while ( !q.empty() && viz[q.top()] == 1 )
            q.pop();
        if ( q.empty() )
            break;
        int p = q.top();
        q.pop();
        viz[p] = 1;
        for ( int i = 0; i < edges[p].size(); ++i ) {
            int newNode = edges[p][i].node;
            if ( dist[p] + edges[p][i].cost < dist[newNode] ) {
                dist[newNode] = dist[p] + edges[p][i].cost;
                q.push ( newNode );
            }
        }
    }
}

void reset () {
    for ( int i = 1; i <= NMAX; ++i ) {
        viz[i] = 0;
        dist[i] = INF;
    }
}

void initHamilton() {
    for ( int i = 0; i < ( 1 <<NMAX ); ++i )
        for ( int j = 0; j <= NMAX; ++j )
            sol[i][j] = INF;
}

int main() {
    int N, M, K;

    fin >> N >> M >> K;
    dest.push_back ( 1 );
    for ( int i = 1; i <= K; ++i ) {
        int d;
        fin >> d;
        dest.push_back ( d );
    }
    dest.push_back ( N );
    K += 2;

    for ( int i = 1; i <= M; ++i ) {
        int x, y, c;
        fin >> x >> y >> c;
        edges[x].push_back ( ( Node ) { y, c } );
        edges[y].push_back ( ( Node ) { x, c } );
    }

    for ( int i = 0; i < K; ++i ) {
        reset();
        dijkstra ( dest[i] );
    }

    initHamilton();

    sol[1][0] = 0;

    for ( int i = 1; i < ( 1 << K ); ++i )
        for ( int j = 1; j < K; ++j ) 
            if ( i & ( 1 << j ) ) 
                for ( int p = 0; p < K; ++p )
                    if ( p != j && ( i & ( 1 << p ) ) )
                        sol[i][j] = std::min ( sol[i][j], sol[i ^ ( 1 << j )][p] + cost[p][j] );
    
    fout << sol[( 1 << K ) - 1][K - 1];

    fin.close();
    fout.close();

    return 0;
}