Cod sursa(job #612215)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 6 septembrie 2011 15:27:02
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.71 kb
#include <iostream>
#include <vector>

#define v first
#define c second
#define Inf 2000000000
#define NMax 2005
#define KMax 17

using namespace std;

vector < pair <int, int> > G[NMax];
vector < pair <int, int> > HG[KMax];
int N, K, Vertex[KMax], DP[1<<KMax][KMax];
int NHeap, Heap[NMax], Pos[NMax], Dist[NMax];

inline int Min (int a, int b)
{
    if (a<b)
    {
        return a;
    }
    return b;
}

inline void Swap (int X, int Y)
{
    int Aux=Pos[Heap[X]];
    Pos[Heap[X]]=Pos[Heap[Y]];
    Pos[Heap[Y]]=Aux;
    Aux=Heap[X];
    Heap[X]=Heap[Y];
    Heap[Y]=Aux;
}

inline bool Compare (int X, int Y)
{
    if (Dist[Heap[X]]<Dist[Heap[Y]])
    {
        return true;
    }
    return false;
}

void Percolate (int X)
{
    int Father=X>>1;
    if (Father>0 and Compare (X, Father))
    {
        Swap (X, Father);
        Percolate (Father);
    }
}

void Sift (int X)
{
    int Son=X<<1;
    if (Son+1<=NHeap and Compare (Son+1, Son))
    {
        ++Son;
    }
    if (Son<=NHeap and Compare (Son, X))
    {
        Swap (X, Son);
        Sift (Son);
    }
}

void Delete (int X)
{
    Swap (X, NHeap);
    Pos[Heap[NHeap]]=0;
    Heap[NHeap]=0;
    --NHeap;
    Sift (X);
}

void Insert (int X)
{
    Heap[++NHeap]=X;
    Pos[X]=NHeap;
    Percolate (NHeap);
}

void InitDijkstra (int Start)
{
    for (int i=1; i<=N; ++i)
    {
        Dist[i]=Inf;
    }
    Heap[1]=Start;
    Pos[Start]=1;
    Dist[Start]=0;
    NHeap=1;
}

void Dijkstra (int Start)
{
    InitDijkstra (Start);
    while (NHeap>0)
    {
        int X=Heap[1];
        Delete (1);
        for (unsigned i=0; i<G[X].size (); ++i)
        {
            int V=G[X][i].v;
            int C=G[X][i].c;
            if (Dist[V]==Inf)
            {
                Insert (V);
            }
            if (Dist[X]+C<Dist[V])
            {
                Dist[V]=Dist[X]+C;
                Percolate (Pos[V]);
            }
        }
    }
}

void BuildGraph ()
{
    for (int i=0; i<K; ++i)
    {
        int X=Vertex[i];
        Dijkstra (X);
        for (int j=0; j<K; ++j)
        {
            int V=Vertex[j];
            int C=Dist[V];
            if (X!=V and C<Inf)
            {
                HG[i].push_back (make_pair (j, C));
            }
        }
    }
}

void InitHamilton (int n)
{
    for (int i=0; i<n; ++i)
    {
        for (int j=0; j<K; ++j)
        {
            DP[i][j]=Inf;
        }
    }
    DP[1][0]=0;
}

void Hamilton ()
{
    int n=1<<K;
    InitHamilton (n);
    for (int Conf=1; Conf<n; ++Conf)
    {
        for (int X=0; X<K; ++X)
        {
            if (!(Conf&(1<<X)))
            {
                continue;
            }
            for (int i=0; i<HG[X].size (); ++i)
            {
                int V=HG[X][i].v;
                int C=HG[X][i].c;
                if (!(Conf&(1<<V)))
                {
                    continue;
                }
                DP[Conf][X]=Min (DP[Conf][X], DP[Conf^(1<<X)][V]+C);
            }
        }
    }
}

void Read ()
{
    freopen ("ubuntzei.in", "r", stdin);
    int M;
    scanf ("%d %d\n%d", &N, &M, &K);
    Vertex[0]=1;
    ++K;
    for (int i=1; i<K; ++i)
    {
        scanf ("%d", &Vertex[i]);
    }
    Vertex[K]=N;
    ++K;
    for (; M>0; --M)
    {
        int X, Y, C;
        scanf ("%d %d %d", &X, &Y, &C);
        G[X].push_back (make_pair (Y, C));
        G[Y].push_back (make_pair (X, C));
    }
}

void Print ()
{
    freopen ("ubuntzei.out", "w", stdout);
    printf ("%d\n", DP[(1<<K)-1][K-1]);
}

int main()
{
    Read ();
    BuildGraph ();
    Hamilton ();
    Print ();
    return 0;
}