Cod sursa(job #1178457)

Utilizator paunmatei7FMI Paun Matei paunmatei7 Data 26 aprilie 2014 17:09:50
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.11 kb
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>

#define x first
#define y second
#define INF 2e9
#define NMAX 2007

using namespace std;

priority_queue< pair< int, int > > q;
int D[27][27];
vector< pair< int, int > > v[NMAX];
int n, m, k;
int Viz[NMAX], V[NMAX];
int Dp[(1 << 19)][27];

void Dijkstra(int X, int d[]){
    while(! q.empty())
        q.pop();
    q.push(make_pair(0, X));
    for(int i = 1; i <= n; ++i){
        d[i] = INF;
        Viz[i] = 0;
    }
    d[X] = 0;
    while(! q.empty()){
        int Nod = q.top().y;
        q.pop();
        for(int i = 0; i < v[Nod].size(); ++i){
            pair< int, int > it = v[Nod][i];
            if(d[it.x] > d[Nod] + it.y){
                d[it.x] = d[Nod] + it.y;
                q.push(make_pair(-d[it.x], it.x));
            }
        }
    }
}

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){
        int x = 0;
        scanf("%d", &V[i]);
    }
    V[++k] = 1;
    V[++k] = n;
    sort(V + 1, V + k + 1);
    for(int i = 1; i <= m; ++i){
        int a, b, c;
        scanf("%d %d %d", &a, &b, &c);
        v[a].push_back(make_pair(b, c));
        v[b].push_back(make_pair(a, c));
    }
    for(int i = 1; i <= k; ++i){
        int d[NMAX];
        Dijkstra(V[i], d);
        for(int j = 1; j <= k; ++j)
            D[i][j] = d[V[j]];
    }
    for(int i = 0; i < (1 << k); ++i)
        for(int j = 1; j <= k; ++j)
            Dp[i][j] = INF;
    for(int i = 2; i <= k; ++i)
        Dp[(1 << (i - 1)) | 1][i] = D[1][i];
    for(int i = 1; i < (1 << k); ++i)
        for(int j = 1; j < k; ++j)
            if(Dp[i][j] != INF)
                for(int l = 2; l <= k; ++l)
                    if(!(i & (1 << (l - 1))))
                        Dp[i | (1 << (l - 1))][j] = min(Dp[i | (1 << (l - 1))][j], Dp[i][j] + D[j][l]);
    int Ans = INF;
    for(int i = 1; i <= k; ++i)
        Ans = min(Ans, Dp[(1 << k) - 1][i]);
    printf("%d\n", Ans);
    return 0;
}