Cod sursa(job #2866151)

Utilizator Tudor_PascaTudor Pasca Tudor_Pasca Data 9 martie 2022 13:28:10
Problema Gather Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>

using namespace std;

typedef long long ll;

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

const ll INF = 1e18;
const int N = 750;
const int K = 15;

struct edge{
    int next, c, d;
};

struct Node {
    int node;
    ll c;
    bool operator <(const Node& other) const {
        return c > other.c;
    }
};

int n, k, m;
int v[K + 5];
ll dp[N + 5][1 << (K + 2)];
vector<edge> adj[N + 5];

ll dijkstra(int start, int minD, int stop) {
    vector<ll> d(N + 5, INF);
    bitset<N + 5> fr;
    priority_queue<Node> pq;
    d[start] = 0;
    pq.push({start, 0});
    while (!pq.empty()) {
        Node top = pq.top();
        int node = top.node;
        pq.pop();
        if (fr[node])
            continue;
        fr[node] = true;
        for (auto it: adj[node]) {
            if (it.d >= minD && d[it.next] > d[node] + it.c) {
                d[it.next] = d[node] + it.c;
                pq.push({it.next, d[it.next]});
            }
        }
    }
    return d[stop];
}

int main() {
    in >> k >> n >> m;
    v[0] = 1;
    for (int i = 1; i <= k; i++)
        in >> v[i];
    k++;
    for (int i = 1; i <= m; i++) {
        int x, y, c, d;
        in >> x >> y >> c >> d;
        adj[x].push_back({y, c, d});
        adj[y].push_back({x, c, d});
    }
    for (int i = 1; i < (1 << k); i++)
        for (int j = 0; j < k; j++)
            dp[j][i] = INF;
    dp[0][1] = 0;
    for (int i = 1; i < (1 << k) - 1; i++) {
        int cnt = 0;
        for (int x = 1; x < k; x++)
            if ((1 << x) & i)
                cnt++;
        for (int x = 0; x < k; x++) {
            if ((1 << x) & i)
                continue;
            for (int y = 0; y < k; y++) {
                if ((1 << y) & i) {
                    ll d = dijkstra(v[y], cnt, v[x]);
                    dp[x][i + (1 << x)] = min(dp[x][i + (1 << x)], dp[y][i] + (cnt + 1) * d);
                    //cout << i << ' ' << v[x] << ' ' << v[y] << ": " << dp[x][i + (1 << x)] << ' ' << dp[y][i] << '\n';
                }
            }
        }
    }
    ll ans = INF;
    for (int i = 0; i < k; i++)
        ans = min(ans, dp[i][(1 << k) - 1]);
    out << ans << '\n';
    return 0;
}