Cod sursa(job #974645)

Utilizator Mihai22eMihai Ionut Enache Mihai22e Data 17 iulie 2013 20:50:55
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <queue>
#include <vector>

#include <cstdio>
#include <cstring>
using namespace std;

const int MAX_N = 2002;
const int MAX_K = 17;
const int INF = 0x3f3f3f3f;

int N, M, K;
int D[MAX_K][MAX_N], dp[1 << MAX_K][MAX_K], temp[MAX_N], a[MAX_K];
vector < pair < int, int > > v[MAX_N];
queue < int > Q;

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

inline void BF(int st, int D[MAX_N]) {
    D[st] = 0;
    Q.push(st);
    while(!Q.empty()) {
        int x = Q.front();
        Q.pop();
        for(size_t i = 0; i < v[x].size(); ++i) {
            int y = v[x][i].first, c = v[x][i].second;
            if(D[x] + c < D[y])
                D[y] = D[x] + c, Q.push(y);
        }
    }
}

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

    scanf("%d %d %d", &N, &M, &K);
    for(int i = 1; i <= K; ++i)
        scanf("%d", &a[i]);
    a[++K] = N;
    for(int i = 1, x, y, c; i <= M; ++i) {
        scanf("%d %d %d", &x, &y, &c);
        v[x].push_back(make_pair(y, c));
        v[y].push_back(make_pair(x, c));
    }

    for(int i = 1; i <= K; ++i) {
        memset(temp, INF, sizeof(temp));
        BF(a[i], temp);
        for(int j = 1; j <= N; ++j)
            D[i][j] = temp[j];
    }
    memset(temp, INF, sizeof(temp));
    BF(1, temp);
    memset(dp, INF, sizeof(dp));
    for(int i = 1, j = 0; i < (1 << K); i *= 2, ++j)
        dp[i][j] = temp[a[j+1]];
    for(int i = 1; i < (1 << K); ++i)
        for(int j = 0; j < K; ++j)
            if(i & (1 << j))
                for(int k = 0; k < K; ++k)
                    if(i & (1 << k) && k != j)
                        dp[i][j] = min(dp[i][j], dp[i^(1 << j)][k] + D[k+1][a[j+1]]);

    printf("%d\n", dp[(1 << K)-1][K-1]);

    fclose(stdin);
    fclose(stdout);

    return 0;
}