Cod sursa(job #997274)

Utilizator FlameingoAiordachioaei Marius Flameingo Data 13 septembrie 2013 17:13:56
Problema Gather Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.35 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#define node first
#define cost second.first
#define capacity second.second
using namespace std;

typedef pair <int, pair <int, int> > graph_node;
const int NMAX = 753, KMAX = 17, INFI = 2e9;

vector <graph_node> G[NMAX];
queue <int> Q;
int V[KMAX], k, N;
long long D[KMAX][KMAX][NMAX], E[1 << KMAX][KMAX];

/// @var D[i][j][k] - distanta minima de la nodul V[i] la nodul k trecand cu j detinuti

inline void bellman_ford (const int &start_node, const int &cap) {

    int cnode;
    Q.push (start_node);
    for (int i = 1; i <= N; ++i)
        D[k][cap][i] = INFI;
    D[k][cap][start_node] = 0;
    while (!Q.empty ()) {
        cnode = Q.front ();
        Q.pop ();
        for (vector <graph_node> :: iterator i = G[cnode].begin (); i != G[cnode].end (); ++i)
            if (D[k][cap][cnode] + (cap + 1) * i->cost < D[k][cap][i->node] && i->capacity >= cap)
                D[k][cap][i->node] = D[k][cap][cnode] + (cap + 1) * i->cost,
                Q.push (i->node);
    }

}

inline int bits (int a) {

    int r = 0;
    while (a)
        a &= a - 1,
        ++r;
    return r;

}

int main () {

    freopen ("gather.in", "r", stdin);
    freopen ("gather.out", "w", stdout);
    int K, M, a, b, c, d, i, l;
    scanf ("%d%d%d", &K, &N, &M);
    for (i = 1; i <= K; ++i)
        scanf ("%d", V + i);
    for (i = 1; i <= M; ++i)
        scanf ("%d%d%d%d", &a, &b, &c, &d),
        G[a].push_back (make_pair (b, make_pair (c, d))),
        G[b].push_back (make_pair (a, make_pair (c, d)));
    for (k = 1; k <= K; ++k)
        for (i = 0; i < K; ++i)
            bellman_ford (V[k], i);
    l = 1 << K;
    k = 0;
    bellman_ford (1, 0);
    for (i = 0; i < l; ++i)
        for (a = 0; a <= K; ++a)
            E[i][a] = INFI;
    for (i = 0; (1 << i) < l; ++i)
        E[1 << i][i] = D[0][0][V[i + 1]];
    for (i = 0; i < l; ++i) {
        c = bits (i) - 1;
        for (a = 0; a < K; ++a)
            if (i & (1 << a))
                for (b = 0; b < K; ++b)
                    if (a != b && i & (1 << b))
                        E[i][a] = min (E[i][a], E[i ^ (1 << a)][b] + D[b + 1][c][V[a + 1]]);
    }
    d = INFI;
    for (i = 0; i < K; ++i)
        if (d > E[l - 1][i])
            d = E[l - 1][i];
    printf ("%d", d);

}