Cod sursa(job #587412)

Utilizator perticas_catalinperticas catalin perticas_catalin Data 4 mai 2011 20:07:35
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.37 kb
#include <iostream>
#include <set>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>

using namespace std;

#define PB push_back
#define MKP make_pair
#define NM 2005
#define inf 2000000000

int dmin[NM], N, M, K, lista[NM], dst[20][20], best[50000][17];

vector <pair <int, int> > G[NM];

void compute_distances(int nod)
{
    set < pair<int, int> > heap;
    int inheap[NM];

    for (int i = 1; i <= N; ++i) dmin[i] = inf, inheap[i] = 1;
    dmin[nod] = 0;

    for (int i = 1; i <= N; ++i) heap.insert(MKP(dmin[i], i));

    for (int n = 1; n <= N; ++n)
    {
        set <pair<int, int> >::iterator it = heap.begin();
        int nodc = it->second;
        heap.erase(it);
        inheap[nodc] = 0;

        for (int i = 0; i < G[nodc].size(); ++i)
        {
            int nnod = G[nodc][i].first;
            int dist = G[nodc][i].second;

            if (!inheap[nnod] || (dmin[nodc] + dist >= dmin[nnod])) continue;

            it = heap.find(MKP(dmin[nnod], nnod));
            if (it != heap.end()) heap.erase(it);
            dmin[nnod] = dmin[nodc] + dist;
            heap.insert(MKP(dmin[nnod], nnod));
        }
    }
}

int main()
{
    freopen ("ubuntzei.in", "r", stdin);
    freopen ("ubuntzei.out", "w", stdout);

    scanf ("%d %d", &N, &M);

    scanf ("%d", &K);

    for (int i = 1; i <= K; ++i) scanf ("%d", &lista[i]);

    lista[0] = 1;

    for (int i = 1; i <= M; ++i)
    {
        int a, b, c;

        scanf ("%d %d %d", &a, &b, &c);
        G[a].PB(MKP(b, c));
        G[b].PB(MKP(a, c));
    }

    for (int i = 0; i <= K; ++i)
    {
        compute_distances(lista[i]);

        for (int j = 0; j <= K; ++j) dst[i][j] = dmin[lista[j]];
        dst[i][K+1] = dmin[N];
    }

    if (K == 0)
    {
        printf ("%d", dst[0][K+1]);

        return 0;
    }

    for (int conf = 0; conf < (1<<K); ++conf)
        for (int i = 0; i <= K; ++i)
            best[conf][i] = inf;

    best[0][0] = 0;

    for (int conf = 1; conf < (1<<K); ++conf)
        for (int i = 0; i < K; ++i)
            if (conf & (1<<i))
            {
                int lconf = conf - (1<<i);
                for (int j = 0; j <= K; ++j) best[conf][i+1] = min (best[lconf][j] + dst[j][i+1], best[conf][i+1]);
            }

    int fbest = inf;

    for (int i = 1; i <= K; ++i) fbest = min (fbest, best[(1<<K) - 1][i] + dst[i][K+1]);

    printf ("%d", fbest);

    return 0;
}