Cod sursa(job #605660)

Utilizator SpiderManSimoiu Robert SpiderMan Data 1 august 2011 16:14:34
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.34 kb
# include <cstring>
# include <cstdio>
# include <deque>
# include <vector>
using namespace std;

const char *FIN = "ubuntzei.in", *FOU = "ubuntzei.out";
const int MAX_N = 10005, MAX_K = 15, oo = 0x3f3f3f3f;

vector < pair <int, int> > G[MAX_N];
int N, M, K, dp[(1 << MAX_K) + 1][MAX_K], nod_1[MAX_N], vecini[MAX_K][MAX_N], C[MAX_K];

void bellman (int S, int *dp) {
    deque <int> Q;
    bool viz[MAX_N];

    for (int i = 0; i <= N; ++i) dp[i] = oo;
    memset (viz, 0, sizeof (viz));
    dp[S] = 0, viz[S] = 1;
    for (Q.push_back (S); ! Q.empty (); Q.pop_front ()) {
        int act = Q.front (); viz[act] = 0;
        for (vector < pair <int, int> > :: iterator it = G[act].begin (); it != G[act].end (); ++it)
            if (dp[act] + it -> second < dp[it -> first]) {
                dp[it -> first] = dp[act] + it -> second;
                if (viz[it -> first] == 0) {
                    Q.push_back (it -> first);
                    viz[it -> first] = 1;
                }
            }
    }
}

inline void getmin (int &a, int b) {
    a = a < b ? a : b;
}

int main (void) {
    freopen (FIN, "r", stdin);

    scanf ("%d %d %d", &N, &M, &K);
    for (int i = 0; i < K; ++i)
         scanf ("%d", C + i);
    for (int x, y, z; M; --M) {
        scanf ("%d %d %d", &x, &y, &z);
        G[x].push_back (make_pair (y, z));
        G[y].push_back (make_pair (x, z));
    }
    bellman (1, nod_1);
    if (K == 0) fprintf (fopen (FOU, "w"), "%d", nod_1[N]);
    else {
        for (int i = 0; i < K; ++i)
            bellman (C[i], vecini[i]);
        for (int i = 1; i < 1 << K; ++i) {
            int stop = 1;
            for (int j = 0; j < K && stop; ++j)
                if (i == 1 << j) {
                    dp[i][j] = nod_1[C[j]];
                    stop = 0;
                }
            if (stop == 0) continue;
            for (int j = 0; j < K; ++j) {
                dp[i][j] = oo;
                if (i & 1 << j)
                    for (int k = 0; k < K; ++k)
                        if (j != k && (i & 1 << k))
                            getmin (dp[i][j], dp[i - (1 << j)][k] + vecini[k][C[j]]);
            }
        }
        int sol = oo;
        for (int i = 0; i < K; ++i)
            getmin (sol, dp[(1 << K) - 1][i] + vecini[i][N]);
        fprintf (fopen (FOU, "w"), "%d", sol);
    }
}