Cod sursa(job #704275)

Utilizator AndrewTheGreatAndrei Alexandrescu AndrewTheGreat Data 2 martie 2012 17:14:51
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <iostream>
#include <stdio.h>
#include <queue>
#include <vector>
#include <utility>
#include <string.h>
#define TR(C, i)\
    for(i = C.begin(); i < C.end(); i++)
#define pb push_back
#define mp make_pair
#define ver first
#define dist second


using namespace std;

const int oo = 0x6f6f6f6f;
const int nmax = 1 << 11;
const int nmic = 17;
int D[nmax];
vector< pair <int, int> > G[nmax];
int C[1 << nmic][nmic], Loc[nmic];
int U[nmic][nmic], N, M, K;

void read()
{
    freopen ("ubuntzei.in", "r", stdin);
    freopen ("ubuntzei.out", "w", stdout);

    scanf("%d %d\n%d", &N, &M, &K);
    int i, a, b, c;
    for(i = 1; i <= K; i++)
        scanf("%d", Loc + i);

    Loc[0] = 1;
    Loc[K + 1] = N;

    for(i = 1; i <= M; i++)
    {
        scanf("%d %d %d", &a, &b, &c);
        G[a].pb(mp(b, c));
        G[b].pb(mp(a, c));
    }
}

struct cmp
{
    bool operator()(const int &a, const int &b)const
    {
        return D[a] > D[b];
    }
};

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

void Dijkstra(int nod)
{
    vector< pair <int, int> >::iterator it;
    memset(D, oo, sizeof(D));
    D[Loc[nod]] = 0;
    Q.push(Loc[nod]);

    int i = nod;

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

        TR(G[nod], it)
            if(D[it->ver] > D[nod] + it->dist)
            {
                D[it->ver] = D[nod] + it->dist;
                Q.push(it->ver);
            }
    }

    nod = i;
    for(i = 0; i <= K + 1; i++)
        U[nod][i] = D[Loc[i]];
}

void dinamica()
{
    memset(C, oo, sizeof(C));

    int bit, mask, nod;

    C[1][0] = 0;

    int L = 1 << (K + 2);
    for(mask = 1; mask < L; mask++)
        for(bit = 0; bit < K + 2; bit++)
            if(mask & (1 << bit))
                for(nod = 0; nod <= K + 1; nod++)
                    if(nod != bit && (mask & (1 << nod)))
                        C[mask][bit] = min(C[mask][bit], C[mask ^ (1 << bit)][nod] + U[nod][bit]);

    printf("%d\n", C[L - 1][K + 1]);
}

int main()
{
    read();
    int i;
    for(i = 0; i <= K; i++)
        Dijkstra(i);
    dinamica();
    return 0;
}