Cod sursa(job #2211064)

Utilizator felixiPuscasu Felix felixi Data 9 iunie 2018 12:12:55
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.02 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 2005;
const int KMAX = 17;
const int INF  = (1 << 29);

int dist[KMAX+5][KMAX+5];
int best[NMAX+5];
vector<pair<int,int>> G[NMAX+5];
int N, K, M;
int prieten[KMAX+2];
int dp[2 << KMAX][KMAX+5];

void dijkstra(int start)
{
    assert(1 <= start && start <= N);

    for( int i = 0;  i <= NMAX;  ++i ) best[i] = INF;
    best[start] = 0;
    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
    pq.push({0, start});
    while( !pq.empty() ) {
        int nod = pq.top().second;
        assert(1 <= nod && nod <= N);

        int cost = pq.top().first;
        pq.pop();
        if( best[nod] < cost ) continue;

        for( auto ed : G[nod] ) {
            int to = ed.first;
            int nc = cost + ed.second;
            if( nc < best[to] ) {
                best[to] = nc;
                pq.push({nc, to});
            }
        }
    }
}

int main()
{
    in >> N >> M;
    in >> K;
    prieten[0] = 1;
    prieten[K + 1] = N;
    for( int i = 1;  i <= K;  ++i ) in >> prieten[i];
    K += 2;

    for( int i = 1;  i <= M;  ++i ) {
        int x,y,c;
        in >> x >> y >> c;
        G[x].push_back({y, c});
        G[y].push_back({x, c});
    }
    for( int i = 0;  i < K;  ++i ){
        dijkstra(prieten[i]);
        for( int j = 0;  j < K;  ++j ) {
            dist[i][j] = best[ prieten[j] ];
            ///cout << dist[i][j] << " \n"[j == K - 1];
        }
    }
    for( int i = 0;  i < (1 << KMAX);  ++i ) for( int j = 0;  j <= KMAX + 1;  ++j )
        dp[i][j] = INF;
    dp[1][0] = 0;
    for( int mk = 0;  mk < (1 << K);  ++mk ) {
        for( int i = 0;  i < K;  ++i ) if( mk & (1 << i) && dp[mk][i] != INF )
        for( int j = 0;  j < K;  ++j ) {
            dp[mk | (1 << j)][j] = min(dp[mk][i] + dist[i][j], dp[mk | (1 << j)][j]);
        }
    }
    out << dp[(1 << K) - 1][K - 1] << '\n';
    return 0;
}