Cod sursa(job #2538804)

Utilizator ArdeleanOficialAlexandru ArdeleanOficial Data 5 februarie 2020 10:11:33
Problema Gather Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.68 kb
#include <bits/stdc++.h>

using namespace std;

const int N = 755, MASK = (1<<15);

struct Edge {
    int v;
    int lng;
    int cap;
};

int dp[N][MASK + 5];

struct Stare {
    int nod;
    int mask;
    int cost;

    bool operator < (const Stare &_) const {
        if (cost == _.cost) {
            if (mask == _.mask)
                return nod < _.nod;
            return mask < _.mask;
        }
        return cost < _.cost;
    }
};

Stare q[N * (MASK + 3)];
vector < Edge > adia[N];
int mask[N];

int Solve_Good()
{
    ifstream fin("gather.in");
    ofstream fout("gather.out");
    int k, n, m, v, a, b, c, d;
    fin >> k >> n >> m;
    for (int i = 0; i < k; ++i)
        fin >> v, mask[v] ^= (1<<i);
    for (int i = 0; i < m; ++i) {
        fin >> a >> b >> c >> d;
        adia[a].push_back({b, c, d});
        adia[b].push_back({a, c, d});
    }
    for (int i = 1; i <= n; ++i)
        for (int msk = 0; msk < (1<<k); ++msk)
            dp[i][msk] = -1;
    dp[1][mask[1]] = 0;
    set < Stare > pq;
    pq.insert({1, 0});
    int ans(1e9 + 7);
    while (pq.size()) {
        auto cur = *pq.begin();
        pq.erase(cur);
        if (cur.cost != dp[cur.nod][cur.mask])
            continue;
        if (cur.mask == (1<<k) - 1)
            ans = min(ans, dp[cur.nod][cur.mask]);
        int sz = __builtin_popcount(cur.mask);

        for (auto i : adia[cur.nod]) {
            if (sz <= i.cap) {
                if (dp[i.v][cur.mask | mask[i.v]] == -1 || dp[i.v][cur.mask | mask[i.v]] > dp[cur.nod][cur.mask] + (sz + 1) * i.lng) {
                    dp[i.v][cur.mask | mask[i.v]] = dp[cur.nod][cur.mask] + (sz + 1) * i.lng;
                    pq.insert({i.v, cur.mask | mask[i.v], dp[i.v][cur.mask | mask[i.v]]});
                }
                if (mask[i.v] | cur.mask != cur.mask && dp[i.v][cur.mask] == -1 || dp[i.v][cur.mask] > dp[cur.nod][cur.mask] + (sz + 1) * i.lng) {
                    dp[i.v][cur.mask] = dp[cur.nod][cur.mask] + (sz + 1) * i.lng;
                    pq.insert({i.v, cur.mask, dp[i.v][cur.mask]});
                }
            }
        }
    }
    fout << ans;
    return 0;
}

namespace Gen {

    void Gen() {
        ofstream fout("gather.in");
    }

    void Solve_Brut() {
        ifstream fin("gather.in");
        ofstream fout("gatherbrut.out");
    }

    bool Check() {

    }
}

int main() {
    int ntst(0);
    while (0) {
        Gen::Gen();
        Gen::Solve_Brut();
        Solve_Good();
        if (Gen::Check())
            cout << "AC " << ++ntst << '\n';
        else {
            cout << "WA\n";
            break;
        }
    }
    Solve_Good();
}