Cod sursa(job #3207642)

Utilizator Mihai_PopescuMihai Popescu Mihai_Popescu Data 26 februarie 2024 17:41:42
Problema Ubuntzei Scor 75
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.23 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

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

#define NMAX 2005
#define INF 1000000000

vector<pair<int, int>> G[NMAX];
int oras[NMAX];
int dist[20][NMAX];
bool viz[NMAX];
int dp[(1 << 15) + 5][20];
priority_queue<pair<int, int>> PQ;

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

    dist[poz][oras[poz]] = 0;
    PQ.push({0, oras[poz]});
    while (PQ.size()) {
        int nod = PQ.top().second;
        PQ.pop();

        if (!viz[nod]) {
            viz[nod] = 1;
            for (auto it : G[nod]) {
                if (dist[poz][nod] + it.second < dist[poz][it.first]) {
                    dist[poz][it.first] = dist[poz][nod] + it.second;
                    PQ.push({-dist[poz][it.first], it.first});
                }
            }
        }
    }
}

int main() {
    int n, m;
    fin >> n >> m;
    int k;
    fin >> k;
    for (int i = 1; i <= k; ++i) {
        fin >> oras[i];
    }
    while (m--) {
        int x, y, z;
        fin >> x >> y >> z;
        G[x].push_back({y, z});
        G[y].push_back({x, z});
    }

    oras[0] = 1;
    dijkstra(0, n);

    for (int i = 1; i <= k; ++i) {
        dijkstra(i, n);
    }

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

    for (int i = 1; i < (1 << k); ++i) {
        for (int j = 0; j < k; ++j) {
            if (i == (1 << j)) {
                dp[i][j] = dist[0][oras[j + 1]];
            } else if (i & (1 << j)) {
                for (int l = 0; l < k; ++l) {
                    if (l != j && (i & (1 << l))) {
                        int cost = dp[i - (1 << j)][l] + dist[l + 1][oras[j + 1]];
                        dp[i][j] = min(dp[i][j], cost);
                    }
                }
            }
        }
    }

    int minim = INF;
    for (int i = 0; i < k; ++i) {
        int cost = dp[(1 << k) - 1][i] + dist[i + 1][n];
        minim = min(minim, cost);
    }

    if (k == 0) {
        minim = dist[0][n];
    }

    fout << minim;
    return 0;
}