Cod sursa(job #2954782)

Utilizator MatteoalexandruMatteo Verzotti Matteoalexandru Data 15 decembrie 2022 12:15:16
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.12 kb
#include <bits/stdc++.h>
#define dbg(x) cerr << #x << ' ' << x << '\n'

using namespace std;

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

using Graph = vector <vector <pair <int, int>>>;

const int INF = 1e9;

void dijkstra(int node, const Graph &g, vector <int> &dist) {
    int n = g.size() - 1;
    dist.resize(1 + n, INF);
    dist[node] = 0;

    priority_queue <pair <int, int>> pq;
    pq.push(make_pair(0, node));
    while (pq.size()) {
        auto [d, from] = pq.top(); d = -d;
        pq.pop();

        if (dist[from] != d)
            continue;

        for (auto to : g[from]) {
            if (dist[to.first] > dist[from] + to.second) {
                dist[to.first] = dist[from] + to.second;
                pq.push(to);
            }
        }
    }
}

int main() {
    int n, m, k;
    vector <int> c;
    Graph g;

    in >> n >> m >> k;
    c.resize(1 + k); g.resize(1 + n);
    c[0] = 1;
    for (int i = 1; i <= k; i++)
        in >> c[i];

    for (int i = 0; i < m; i++) {
        int x, y, w;
        in >> x >> y >> w;
        g[x].push_back(make_pair(y, w));
        g[y].push_back(make_pair(x, w));
    }
    vector <vector <int>> distances(1 + k);
    for (int i = 0; i <= k; i++)
        dijkstra(c[i], g, distances[i]);

    vector <vector <int>> dp(1 + k, vector <int>(1 << k + 1, INF));
    // dp[k][mask] = minimum distance to visit all nodes in mask and last node is k
    dp[0][1] = 0;

    for (int mask = 3; mask < (1 << k + 1); mask += 2) {
        for (int i = 1; i <= k; i++) {
            if (mask & (1 << i)) {
                for (int j = 0; j <= k; j++) {
                    if (mask & (1 << j)) {
                        dp[i][mask] = min(dp[i][mask],
                                          dp[j][mask ^ (1 << i)] + distances[j][i]);
                    }
                }
            }
        }
    }

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

    out << ans << '\n';
    return 0;
}