Cod sursa(job #2636019)

Utilizator robertrRotaru Stefan Robert robertr Data 16 iulie 2020 12:38:26
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.31 kb
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>
using namespace std;
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");
int n, m, k;
int T[2005], P[20][2005], DP[(1<<15) + 5][16], C[16];
vector<vector<pair<int, int>>> Graph(2005);
void Dijkstra(int d[], int src) {
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    bitset<2005> viz;
    d[src] = 0;
    pq.emplace(0, src);
    while(!pq.empty()) {
        int u = pq.top().second;
        pq.pop();
        viz[u] = 1;
        for(auto &&i : Graph[u]) {
            int v = i.first, pay = i.second;
            if(!viz[v] && d[u] + pay < d[v]) {
                d[v] = d[u] + pay;
                pq.emplace(d[v], v);
            }
        }
    }
}
void Read() {
    f >> n >> m >> k;
    for(int i = 1; i <= k; ++i) {
        f >> C[i];
    }
    for(int i = 1; i <= m; ++i) {
        int x, y, z;
        f >> x >> y >> z;
        Graph[x].push_back({y, z});
        Graph[y].push_back({x, z});
    }
}
void Initiate() {
    for(int i = 1; i <= n; ++i) {
        T[i] = INT_MAX;
    }
    Dijkstra(T, 1);
    for(int i = 1; i <= k; ++i) {
        for(int j = 1; j <= n; ++j) {
            P[C[i]][j] = INT_MAX;
        }
        Dijkstra(P[C[i]], C[i]);
    }
    for(int i = 1; i < (1 << k); ++i) {
        for(int j = 1; j <= k; ++j) {
            DP[i][j] = INT_MAX;
        }
    }
}
void Solve() {
    Initiate();
    for(int i = 1; i < (1 << k); ++i) {
        for(int j = 1; j <= k; ++j) {
            if(i & (1 << (j - 1))) {
                if(i == (1 << (j - 1))) {
                    DP[i][j] = T[C[j]];
                }
                else {
                    int ant = i - (1 << (j - 1));
                    for(int p = 1; p <= k; ++p) {
                        DP[i][j] = min(DP[i][j], DP[ant][p] + P[C[p]][C[j]]);
                    }
                }
            }
        }
    }
}
void Write() {
    Read();
    if(k == 0) {
        Dijkstra(T, 1);
        g << T[n] << '\n';
    }
    else {
        Solve();
        int sol = INT_MAX;
        for(int i = 1; i <= k; ++i) {
            sol = min(sol, DP[(1 << k) - 1][i] + P[C[i]][n]);
        }
        g << sol << '\n';
    }
}
int main()
{
    Write();
    return 0;
}