Cod sursa(job #3292259)

Utilizator cosminccc7Cazacu Cosmin cosminccc7 Data 7 aprilie 2025 18:48:51
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.23 kb
#include <bits/stdc++.h>
using namespace std;

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

const int INF = 1e9;

int n, m, k;
int nr[2001];
vector<vector<int>> dp(1 << 16, vector<int>(21, INF));
vector<int> obl;
vector<vector<int>> distanta(21, vector<int>(2000, INF));
vector<vector<pair<int, int>>> muchii(2000);
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;

void dijkstra(int idx, int start) {
    distanta[idx][start] = 0;
    pq.push({0, start});

    while (!pq.empty()) {
        int d = pq.top().first;
        int u = pq.top().second;
        pq.pop();

        if (d > distanta[idx][u]) continue;

        for (auto [v, cost] : muchii[u]) {
            if (distanta[idx][v] > distanta[idx][u] + cost) {
                distanta[idx][v] = distanta[idx][u] + cost;
                pq.push({distanta[idx][v], v});
            }
        }
    }
}

int main() {
    in >> n >> m >> k;

    obl.push_back(0); // start node
    for (int i = 1; i <= k; ++i) {
        int x;
        in >> x;
        --x;
        obl.push_back(x);
        nr[x] = i;
    }

    k++; // total number of mandatory nodes including node 0

    for (int i = 0; i < m; ++i) {
        int x, y, z;
        in >> x >> y >> z;
        --x; --y;
        muchii[x].emplace_back(y, z);
        muchii[y].emplace_back(x, z);
    }

    // Dijkstra for each mandatory node
    for (int i = 0; i < k; ++i) {
        dijkstra(i, obl[i]);
    }

    // Initialize dp
    dp[1][0] = 0; // Only node 0 visited

    for (int mask = 1; mask < (1 << k); ++mask) {
        for (int u = 0; u < k; ++u) {
            if (!(mask & (1 << u))) continue;
            for (int v = 0; v < k; ++v) {
                if (mask & (1 << v)) continue;
                int new_mask = mask | (1 << v);
                dp[new_mask][v] = min(dp[new_mask][v], dp[mask][u] + distanta[u][obl[v]]);
            }
        }
    }

    // Final result: reach node n - 1 from any final obligatory node
    int rezultat = INF;
    for (int i = 0; i < k; ++i) {
        if (distanta[i][n - 1] < INF)
            rezultat = min(rezultat, dp[(1 << k) - 1][i] + distanta[i][n - 1]);
    }

    out << rezultat << '\n';
}