Cod sursa(job #3200164)

Utilizator victor_gabrielVictor Tene victor_gabriel Data 3 februarie 2024 18:16:31
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.08 kb
#include <fstream>
#include <climits>
#include <vector>
#include <queue>

using namespace std;

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

typedef pair<int, int> Pair;
const int DIM = 2010;
const int EXP = 18;

int n, m, cnt, x, y, c;
int v[DIM], dist[EXP + 5][DIM], dp[(1 << (EXP)) + 1][EXP + 5];
vector<Pair> l[DIM];
priority_queue <Pair, vector<Pair>,greater <Pair>> q;

void dijkstra(int ind, int start) {
    for (int i = 1; i <= n; i++)
        dist[ind][i] = INT_MAX;
    dist[ind][start] = 0;
    q.emplace(0, start);

    while (!q.empty()) {
        int cost = q.top().first;
        int node = q.top().second;
        q.pop();

        if (dist[ind][node] != cost)
            continue;

        for (auto adjElem : l[node]) {
            int adjNode = adjElem.first;
            int adjCost = adjElem.second;
            int newCost = cost + adjCost;

            if (dist[ind][adjNode] > newCost) {
                dist[ind][adjNode] = newCost;
                q.emplace(dist[ind][adjNode], adjNode);
            }
        }
    }
}

int main() {
    fin >> n >> m >> cnt;
    for (int i = 1; i <= cnt; i++)
        fin >> v[i];
    v[0] = 1;
    v[++cnt] = n;
    cnt++;

    for (int i = 1; i <= m; i++) {
        fin >> x >> y >> c;
        l[x].emplace_back(y, c);
        l[y].emplace_back(x, c);
    }

    for (int i = 0; i < cnt; i++)
        dijkstra(i, v[i]);

    for (int mask = 1; mask < (1 << cnt); mask++)
        for (int i = 0; i < cnt; i++)
            dp[mask][i] = INT_MAX;

    dp[1][0] = 0;
    for (int mask = 1; mask < (1 << cnt); mask++) {
        for (int prev = 0; prev < cnt; prev++) {
            if (!(mask & (1 << prev)) || dp[mask][prev] == INT_MAX)
                continue;

            for (int i = 0; i < cnt; i++) {
                if ((mask & (1 << i)))
                    continue;

                int newMask = (mask | (1 << i));
                if (dp[newMask][i] > dp[mask][prev] + dist[i][v[prev]])
                    dp[newMask][i] = dp[mask][prev] + dist[i][v[prev]];
            }
        }
    }

    fout << dp[(1 << cnt) - 1][cnt - 1];

    return 0;
}