Cod sursa(job #1107966)

Utilizator Stefex09Stefan Teodorescu Stefex09 Data 15 februarie 2014 12:06:33
Problema Ubuntzei Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.13 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>

using namespace std;

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

const int MAXN = 2010;
typedef pair <int, int> PII;

vector <PII> Graf[MAXN];
int Best[20][20];
int DP[1 << 17][20];
int Cost[MAXN];
int V[20];

struct comp
{
    inline bool operator () (const int &A, const int &B) const
    {
        return Cost[A] < Cost[B];
    }
};

priority_queue <int, vector <int>, comp> Q;

void Dijkstra (int S)
{
    int nod;
    vector <PII> :: iterator it;
    memset (Cost, 0x3f, sizeof (Cost));
    Q.push (S);
    Cost[S] = 0;

    while (!Q.empty ()){
        nod = Q.top ();
        Q.pop ();

        for (it = Graf[nod].begin (); it != Graf[nod].end (); ++ it)
            if (Cost[nod] + (it -> second) < Cost[it -> first]){
                Cost[it -> first] = Cost[nod] + (it -> second);
                Q.push (it -> first);
            }
    }
}

int main()
{
    int N, M, K, a, b, c, i, j;

    in >> N >> M;
    in >> K;
    for (i = 1; i <= K; i ++)
        in >> V[i];
    V[++ K] = 1;
    V[++ K] = N;
    sort (V + 1, V + K + 1);

    while (M --){
        in >> a >> b >> c;
        Graf[a].push_back (make_pair (b, c));
        Graf[b].push_back (make_pair (a, c));
    }

    for (i = 1; i <= K; i ++){
        Dijkstra (V[i]);

        for (j = 1; j <= K; j ++)
            Best[i][j] = Cost[V[j]];
    }

    for (i = 1; i < (1 << K); i ++)
        for (j = 1; j <= K; j ++)
            DP[i][j] = (1 << 30);

    for (i = 2; i <= K; i ++)
        DP[(1 << (i - 1)) | 1][i] = Best[1][i];

    for (i = 1; i < (1 << K); i += 2)
        for (j = 1; j < K; j ++)
            if (DP[i][j] != (1 << 30))
                for (c = 2; c <= K; c ++)
                    if (!(i & (1 << (c - 1))))
                        DP[i | (1 << (c - 1))][c] = min (DP[i | (1 << (c - 1))][c], DP[i][j] + Best[j][c]);

    int Ans = (1 << 30);
    for (i = 1; i <= K; i ++)
        Ans = min (Ans, DP[(1 << K) - 1][i]);

    out << Ans;

    return 0;
}