Cod sursa(job #1602129)

Utilizator algebristulFilip Berila algebristul Data 16 februarie 2016 16:13:12
Problema Gather Scor 10
Compilator cpp Status done
Runda contest_3 Marime 2.69 kb
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

const int nmax = 752;

int nodes[nmax];
int idx[nmax];
int k, n, m;
vector<int> A[nmax];
vector<int> C[nmax];
vector<int> L[nmax];
long long D[16][16][16];
vector<pair<int, int> > next[16][32768];
long long dp[16][32768];
const long long INF = 0x3f3f3f3f3f3f3f3fLL;

int numbits(int x) {
    int y = 0;
    while (x) {
        y++;
        x = x & (x-1);
    }

    return y;
}

void build() {
    for (int l = 0; l <= k; l++) {
        for (int i = 1; i <= k; i++) {
            bool inq[752];
            long long d[752];
            memset(d, 0x3f3f3f3f, sizeof(d));
            memset(inq, 0, sizeof(inq));
            queue<int> q;
            q.push(nodes[i - 1]);
            d[nodes[i - 1]] = 0;
            inq[nodes[i - 1]] = 1;
            while (!q.empty())  {
                int x = q.front();
                q.pop();
                inq[x] = 0;

                for (int i = 0; i < A[x].size(); i++) {
                    int y = A[x][i];
                    if (L[x][i] < l)
                        continue;
                    if (d[y] > d[x] + (l + 1) * C[x][i]) {
                        d[y] = d[x] + (l + 1) * C[x][i];
                        if (!inq[y]) {
                            q.push(y);
                            inq[y] = 1;
                        }
                    }
                }
            }
            for (int j = 1; j <= k; j++) {
                D[l][i][j] = d[nodes[j-1]];
            }
        }
    }

    memset(dp, 0x3f3f3f3f, sizeof(dp));

    for (int i = 1; i <= k; i++) {
        dp[i][(1<<(i-1))] = D[0][1][i];
    }

    for (int m = 0; m < (1<<k); m++) {
        for (int i = 1; i <= k; i++) {
            if ((m & (1<<(i-1))) == 0)
                continue;
            for (int j = 1; j <= k; j++) {
                if (m & (1<<(j-1)))
                    continue;
                dp[j][m + (1<<(j-1))] = min(dp[j][m + (1<<(j-1))], dp[i][m] + D[numbits(m)][i][j]);
            }
        }
    }
}

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

    scanf("%d %d %d", &k, &n, &m);

    for (int i = 1; i <= n; i++) idx[i] = -1;

    for (int i = 0; i < k; i++) {
        scanf("%d", &nodes[i]);
        idx[nodes[i]] = i;
    }

    for (int i = 1, a, b, c, d; i <= m; i++) {
        scanf("%d %d %d %d", &a, &b, &c, &d);

        A[a].push_back(b);
        A[b].push_back(a);

        C[a].push_back(c);
        C[b].push_back(c);

        L[a].push_back(d);
        L[b].push_back(d);
    }

    build();

    long long ans = INF;
    for (int i = 1; i <= k; i++) {
        ans = min(ans, dp[i][(1<<k)-1]);
    }

    printf("%lld\n", ans);

    return 0;
}