Cod sursa(job #3338283)

Utilizator TeogaloiuTeodor Galoiu Teogaloiu Data 2 februarie 2026 10:20:49
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.68 kb
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
#include <algorithm>
#include <cstring>
using namespace std;

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

struct heapNode {
    int node;
    int cost;
    bool operator < (const heapNode& a) const {
        return cost > a.cost;
    }
};

const int MAXN = 2005;
const int MAXK = 17;
const int INF = 1000000000;

vector<heapNode> graph[MAXN];
int dist[MAXK][MAXN];
int toSpecial[MAXN];
int fromSpecial[MAXK];
int specialDist[MAXK][MAXK];
int k;

int dp[1 << 15][15];

void dijkstra(int start, int idx, int n) {
    for (int i = 1; i <= n; i++) {
        dist[idx][i] = INF;
    }
    dist[idx][start] = 0;

    priority_queue<heapNode> pq;
    pq.push({start, 0});

    while (!pq.empty()) {
        heapNode current = pq.top();
        pq.pop();

        if (current.cost != dist[idx][current.node]) {
            continue;
        }

        for (auto& edge : graph[current.node]) {
            int neighbor = edge.node;
            int newCost = current.cost + edge.cost;

            if (newCost < dist[idx][neighbor]) {
                dist[idx][neighbor] = newCost;
                pq.push({neighbor, newCost});
            }
        }
    }
}

int main() {
    int n, m;
    cin >> n >> m >> k;

    vector<int> specials(k);
    for (int i = 0; i < k; i++) {
        cin >> specials[i];
    }

    vector<int> allSpecials;
    allSpecials.push_back(1);
    for (int i = 0; i < k; i++) {
        allSpecials.push_back(specials[i]);
    }
    allSpecials.push_back(n);

    int totalSpecial = allSpecials.size();
    for (int i = 0; i < m; i++) {
        int x, y, z;
        cin >> x >> y >> z;
        graph[x].push_back({y, z});
        graph[y].push_back({x, z});
    }

    memset(toSpecial, -1, sizeof(toSpecial));
    for (int i = 0; i < totalSpecial; i++) {
        fromSpecial[i] = allSpecials[i];
        toSpecial[allSpecials[i]] = i;
    }

    for (int i = 0; i < totalSpecial; i++) {
        dijkstra(allSpecials[i], i, n);
    }

    if (k == 0) {
        cout << dist[0][n] << "\n";
        return 0;
    }

    for (int i = 0; i < totalSpecial; i++) {
        for (int j = 0; j < totalSpecial; j++) {
            specialDist[i][j] = dist[i][fromSpecial[j]];
            if (specialDist[i][j] >= INF) {
                specialDist[i][j] = INF;
            }
        }
    }

    int maskCount = (1 << k);

    for (int mask = 0; mask < maskCount; mask++) {
        for (int last = 0; last < k; last++) {
            dp[mask][last] = INF;
        }
    }

    for (int i = 0; i < k; i++) {
        dp[1 << i][i] = specialDist[0][i + 1];
    }

    for (int mask = 0; mask < maskCount; mask++) {
        for (int last = 0; last < k; last++) {
            if (dp[mask][last] >= INF) continue;

            for (int next = 0; next < k; next++) {
                if (mask & (1 << next)) continue;

                int newMask = mask | (1 << next);
                int newCost = dp[mask][last] + specialDist[last + 1][next + 1];

                if (newCost < dp[newMask][next]) {
                    dp[newMask][next] = newCost;
                }
            }
        }
    }

    int answer = INF;
    int endIndex = totalSpecial - 1;

    for (int last = 0; last < k; last++) {
        if (dp[maskCount - 1][last] >= INF) continue;

        int totalCost = dp[maskCount - 1][last] + specialDist[last + 1][endIndex];
        if (totalCost < answer) {
            answer = totalCost;
        }
    }

    if (answer >= INF) {
        answer = -1;
    }

    cout << answer << "\n";

    return 0;
}