Cod sursa(job #1366807)

Utilizator tudorv96Tudor Varan tudorv96 Data 1 martie 2015 13:53:30
Problema Gather Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.26 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

ifstream fin ("gather.in");
ofstream fout ("gather.out");

const int N = 755, P = 17, oo = 2e9;

int d[N][1 << P], n, m;
short k, det[N], nr[1 << P];
vector <pair <short, pair <int, short> > > g[N];
queue <pair <short, short> > Q;
vector <bool> inq[N];

int main() {
    fin >> k >> n >> m;
    for (int x, i = 0; i < k; ++i) {
        fin >> x;
        det[x] = 1 << i;
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j < (1 << k); ++j)
            d[i][j] = oo;
        inq[i].resize((1 << k), 0);
    }
    for (int x, y, mx, c; m; --m) {
        fin >> x >> y >> c >> mx;
        g[x].push_back(make_pair (y, make_pair(c, mx)));
        g[y].push_back(make_pair (x, make_pair(c, mx)));
    }
    for (int i = 1; i < (1 << k); ++i)
        for (int j = 0; j < k; ++j)
            if (i & (1 << j))
                nr[i]++;
    d[1][0] = 0;
    Q.push(make_pair(1, 0));
    while (Q.size()) {
        int x = Q.front().first, dt = Q.front().second;
        inq[x][dt] = 0;
        Q.pop();
        if (nr[dt] == k) {
            fout << d[x][dt] << "\n";
            return 0;
        }
        for (vector <pair <short, pair <int, short> > > :: iterator it = g[x].begin(); it != g[x].end(); ++it)
            if (nr[dt] <= it -> second.second) {
                if (d[x][dt] + it -> second.first * (nr[dt] + 1) < d[it -> first][dt]) {
                    d[it -> first][dt] = d[x][dt] + it -> second.first * (nr[dt] + 1);
                    if (!inq[it -> first][dt]) {
                        inq[it -> first][dt] = 1;
                        Q.push(make_pair (it -> first, dt));
                    }
                }
                if (det[it -> first] && d[x][dt] + it -> second.first * (nr[dt] + 1) < d[it -> first][dt | det[it -> first]]) {
                    d[it -> first][dt | det[it -> first]] = d[x][dt] + it -> second.first * (nr[dt] + 1);
                    if (!inq[it -> first][dt | det[it -> first]]) {
                        inq[it -> first][dt | det[it -> first]] = 1;
                        Q.push(make_pair (it -> first, (dt | det[it->first])));
                    }
                }
            }
    }
}