Cod sursa(job #1240311)

Utilizator iordache.bogdanIordache Ioan-Bogdan iordache.bogdan Data 11 octombrie 2014 00:10:48
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.28 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#define DIM 2005
#define DIMV (1 << 15)
#define DIMK 20
#define INF (1 << 30)
#define pt(x) (1 << (x))
#define vint vector< pair<int, int> >::iterator
#define infile "ubuntzei.in"
#define outfile "ubuntzei.out"

using namespace std;

ifstream f(infile);
ofstream g(outfile);

vector< pair<int, int> > L[DIM];

queue<int> Q;

int n, m, k, a, b, c;

int prior[DIM], D[DIM], Dist[DIM][DIM], DP[DIMK][DIMV];

bool ok[DIM];

void BF(int source) {
    for (int i = 1; i <= n; ++i)
        D[i] = INF;
    D[prior[source]] = 0;
    memset(ok, 0, sizeof(ok));
    Q.push(prior[source]);
    while (!Q.empty()) {
        int nod = Q.front();
        Q.pop();
        ok[nod] = 0;
        for (vint it = L[nod].begin(); it != L[nod].end(); ++it)
        if (D[nod] + it -> second < D[it -> first]) {
            D[it -> first] = D[nod] + it -> second;
            if (!ok[it -> first]) {
                ok[it -> first] = 1;
                Q.push(it -> first);
            }
        }
    }
    for (int i = 0; i <= k + 1; ++i)
        Dist[source][i] = D[prior[i]];
}

int main () {
    f >> n >> m >> k;
    for (int i = 1; i <= k; ++i)
        f >> prior[i];
    prior[0] = 1;
    prior[k + 1] = n;
    for (int i = 1; i <= m; ++i) {
        f >> a >> b >> c;
        L[a].push_back(make_pair(b, c));
        L[b].push_back(make_pair(a, c));
    }
    for (int i = 0; i <= k + 1; ++i)
        BF(i);
    for (int i = 0; i <= k; ++i)
        for (int j = 0; j < pt(k); ++j)
            DP[i][j] = INF;
    DP[0][0] = 0;
    for (int config = 0; config < pt(k); ++config)
        for (int i = 0; i <= k; ++i)
            if (DP[i][config] != INF)
                for (int j = 1; j <= k; ++j)
                    if ( (config & pt(j - 1)) == 0)
                        DP[j][config | pt(j - 1)] = std::min(DP[j][config | pt(j - 1)], DP[i][config] + Dist[i][j]);
    int SOL = INF;
    for (int i = 1; i <= k; ++i)
        SOL = std::min(SOL, DP[i][pt(k) - 1] + Dist[i][k + 1]);
    if (k == 0)
        SOL = Dist[0][1];
    g << SOL << "\n";
    return 0;
}

//This room. This bullet. There's a bullet for everyone. And a time. And a place. Yes... maybe this is how it has to be. - 47