Cod sursa(job #2184281)

Utilizator amaliarebAmalia Rebegea amaliareb Data 23 martie 2018 21:51:05
Problema Gather Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.87 kb
#include <bits/stdc++.h>
#define ll long long

using namespace std;
ifstream f("gather.in");
ofstream g("gather.out");
int n, m, k;
ll d[1 << 15][16], dist[16][16][16], tdist[755], cell[16];
struct miau{int node; ll cost, lim;};
vector<miau> gr[755];

void Dijkstra(int start, int nr) {
    memset(tdist, 0, sizeof tdist);
    priority_queue<pair<ll, int> > pq;
    pq.push({-1, start});
    while (!pq.empty()) {
        int node = pq.top().second;
        if (!tdist[node]) {
            tdist[node] = -pq.top().first;
            for (auto son: gr[node])
                if (!tdist[son.node] && son.lim >= nr)
                    pq.push({-tdist[node] - son.cost, son.node});
        }
        pq.pop();
    }
}

int main()
{
    f >> k >> n >> m;
    for (int i = 0; i < k; ++i) f >> cell[i];
    for (int i = 1; i <= m; ++i) {
        ll a, b, c, d;
        f >> a >> b >> c >> d;
        gr[a].push_back({b, c, d});
        gr[b].push_back({a, c, d});
    }
    for (int i = 0; i < k; ++i)
        for (int p = 1; p <= k; ++p) {
            Dijkstra(cell[i], p);
            for (int j = 0; j < k; ++j) dist[i][j][p] = tdist[cell[j]] - 1;
        }
    Dijkstra(1, 0);
    for (int i = 0; i < k; ++i) d[(1 << i)][i] = tdist[cell[i]] - 1;
    for (int mask = 1; mask < (1 << k); ++mask) {
        if (__builtin_popcount(mask) == 1) continue;
        for (int p = 0; p < k; ++p) if (mask & (1 << p)) {
            d[mask][p] = 1LL << 50;
            int pm = mask - (1 << p);
            ll cnt = 0;
            for (int q = 0; q < k; ++q) if (pm & (1 << q)) ++cnt;
            for (int q = 0; q < k; ++q) if (pm & (1 << q)) d[mask][p] = min(d[mask][p], d[pm][q] + 1LL * dist[q][p][cnt] * (cnt + 1));
        }
    }
    ll mini = 1LL << 50;
    for (int i = 0; i < k; ++i) mini = min(mini, d[(1 << k) - 1][i]);
    g << mini << '\n';
    return 0;
}