Cod sursa(job #3259858)

Utilizator cinavalptopscalaCont laptop in scoala cinavalptopscala Data 28 noiembrie 2024 10:38:49
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.04 kb
#include<fstream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;

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

const int Inf = 1e9;

int n;
vector<int> Ks;
vector<pair<int, int>> G[2000];
int dp[(1 << 15) + 1][15];
vector<vector<int>> dists; // WARNING: starts with 1 (0 is reserved for first node)

void Dijkstra(int start, vector<int> &output) {
    output = vector<int>(n, Inf);
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> Q;
    Q.emplace(output[start] = 0, start);
    while(!Q.empty()) {
        auto [dist, x] = Q.top();
        Q.pop();
        if(output[x] < dist) continue;
        for(auto [weight, y] : G[x]) {
            if(output[x] + weight < output[y]) {
                Q.emplace(output[y] = output[x] + weight, y);
            }
        }
    }
}

int main() {
    memset(dp, 0x7f, sizeof(dp));
    int m, k, x, y, w;
    cin >> n >> m >> k;
    Ks.resize(k);
    dists.resize(k + 1);
    for(int &kv : Ks) {
        cin >> kv;
        --kv;
    }
    for(int i=0; i<m; ++i) {
        cin >> x >> y >> w;
        G[--x].emplace_back(w, --y);
        G[y].emplace_back(w, x);
    }
    Dijkstra(0, dists[0]);
    if(k < 1) {
        cout << dists[0][n-1];
        return 0;
    }
    for(int i=1; i<=k; ++i)
        Dijkstra(Ks[i-1], dists[i]);
    /*for(auto d : dists) {
        for(int a : d)
            cout << a << ' ';
        cout << '\n';
    }*/
    for(int i=0; i<k; ++i)
        dp[1 << i][i] = dists[0][Ks[i]];
    for(int i=1; i<(1<<k)-1; ++i) {
        for(int j=0; j<k; ++j)
            if(!(i & (1 << j))) {
                int n_mask = i | (1 << j);
                for(int l=0; l<k;++l)
                    dp[n_mask][j] = min(dp[n_mask][j], dp[i][l] + dists[l+1][Ks[j]]);
            }
    }
    /*for(int i=1; i<(1<<k); ++i){
        for(int j=0; j<k;++j)
            cout << dp[i][j] << ' ';
        cout << '\n';
    }*/
    int min_dist = Inf;
    for(int j=0; j<k;++j)
        min_dist = min(min_dist, dp[(1 << k) - 1][j] + dists[j+1][n-1]);
    cout << min_dist;
}