Cod sursa(job #968121)

Utilizator vali.lazarLazar Valentin vali.lazar Data 1 iulie 2013 20:18:58
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.13 kb
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;

#define Nmax 2010
#define PI pair<int, int>
#define pb push_back
#define mp make_pair
#define f first
#define s second
#define Inf 0x3f3f3f3f

int N, M, X, Y, Z, K, C[16], Dist[Nmax][Nmax], Dp[1 << 16][16];
vector<PI> G[Nmax];
priority_queue<PI, vector<PI>, greater<PI> > Q;


void Dijkstra(int StartNode, int V[])
{
    for(int i = 1; i <= N; ++ i)
        V[i] = Inf;
    Q.push(mp(0, StartNode));
    V[StartNode] = 0;
    while(!Q.empty())
    {
        int Node = Q.top().s;
        Q.pop();
        for(vector<PI> :: iterator it = G[Node].begin(); it != G[Node].end(); ++ it)
            if(V[it -> f] > V[Node] + it -> s)
            {
                V[it -> f] = V[Node] + it -> s;
                Q.push(mp(V[it -> f], it -> f));
            }
    }
}

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

    scanf("%i %i", &N, &M);
    scanf("%i", &K);
    for(int i = 0; i < K; ++ i)
        scanf("%i", &C[i]);
    for(int i = 1; i <= M; ++ i)
    {
        scanf("%i %i %i", &X, &Y, &Z);
        G[X].pb(mp(Y, Z));
        G[Y].pb(mp(X, Z));
    }

    for(int i = 1; i <= N; ++ i)
        Dijkstra(i, Dist[i]);

    if(K == 0)
    {
        printf("%i\n", Dist[1][N]);
        return 0;
    }
    memset(Dp, Inf, sizeof(Dp));

    for(int i = 0; i < K; ++ i) Dp[1 << i][i] = Dist[1][ C[i] ];

    for(int Conf = 1; Conf < (1 << K); ++ Conf)
    {
        vector<int> Bit;
        for(int i = 0; i < K; ++ i)
            if(Conf & (1 << i))
                Bit.push_back(i);

        for(int i = 0; i < Bit.size(); ++ i)
            for(int j = 0; j < Bit.size(); ++ j)
                if(i != j)
                    Dp[Conf][Bit[i]] = min(Dp[Conf][Bit[i]], Dp[Conf ^ (1 << Bit[i])][Bit[j]] + Dist[ C[ Bit[j] ] ][ C[ Bit[i] ] ]);
    }

    int Ans = Inf;
    for(int i = 0; i < K; ++ i)
            Ans = min(Ans, Dp[(1 << K) - 1][i] + Dist[ C[i] ][N]);

    printf("%i\n", Ans);
    return 0;
}