Cod sursa(job #997206)

Utilizator FlameingoAiordachioaei Marius Flameingo Data 13 septembrie 2013 15:24:50
Problema Ubuntzei Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.05 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#include <cstring>
#define nod first
#define cost second
using namespace std;

const int NMAX = 2003, KMAX = 17, INFI = 2e9;

int k, D[KMAX][NMAX], DP[1 << KMAX][KMAX], V[KMAX], aux[NMAX];

/// @var D[i][j] distanta minima de la V[i] la j

struct compare {

    bool operator () (const int &a, const int &b) {

        return D[k][a] < D[k][b];

    }

};

vector <pair <int, int> > G[NMAX];
priority_queue <int, vector <int>, compare> Q;

inline void dijkstra (const int &a) {

    int node;
    Q.push (a);
    D[k][a] = 0;
    while (!Q.empty ()) {
        node = Q.top ();
        Q.pop ();
        for (vector <pair <int, int> > :: iterator i = G[node].begin (); i != G[node].end (); ++i)
            if (D[k][node] + i->cost < D[k][i->nod])
                D[k][i->nod] = D[k][node] + i->cost,
                Q.push (i->nod);
    }

}

int main () {

    freopen ("ubuntzei.in", "r", stdin);
    freopen ("ubuntzei.out", "w", stdout);
    int N, M, K, i, a, b, c, l;
    scanf ("%d%d%d", &N, &M, &K);
    for (i = 1; i <= K; ++i)
        scanf ("%d", V + i);
    V[++K] = N;
    for (i = 1; i <= M; ++i)
        scanf ("%d%d%d", &a, &b, &c),
        G[a].push_back (make_pair (b, c)),
        G[b].push_back (make_pair (a, c));

    for (k = 1; k <= K; ++k) {
        for (a = 1; a <= N; ++a)
            D[k][a] = INFI;
        dijkstra (V[k]);
    }
    l = 1 << K;
    for (i = 0; i < l; ++i)
        for (a = 0; a <= K; ++a)
            DP[i][a] = INFI;
    k = K + 1;
    for (i = 1; i <= N; ++i)
        D[k][i] = INFI;
    dijkstra (1);
    for (i = 0; (1 << i) < l; ++i)
        DP[1 << i][i] = D[K + 1][V[i + 1]];
    for (i = 1; i < l; ++i)
        for (a = 0; a < K; ++a)
            if (i & (1 << a))
                for (b = 0; b < K; ++b)
                    if (b != a && (i & (1 << b)))
                        DP[i][a] = min (DP[i][a], DP[i ^ (1 << a)][b] + D[b + 1][V[a + 1]]);
    printf ("%d", DP[l - 1][K - 1]);

}