Cod sursa(job #2707827)

Utilizator vlad082002Ciocoiu Vlad vlad082002 Data 17 februarie 2021 19:23:30
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.56 kb
#include <bits/stdc++.h>
using namespace std;

int n, m, k, c[2048];
vector<pair<int, int> > g[2048];

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

int main() {
    fin >> n >> m >> k;
    c[0] = 1, c[k+1] = n;
    for(int i = 1; i <= k; i++)
        fin >> c[i];

    while(m--) {
        int u, v, c;
        fin >> u >> v >> c;
        g[u].push_back({v, c});
        g[v].push_back({u, c});
    }

    vector<vector<int> >dist(k+2, vector<int> (n+1, 2e9)); // dist[i][j] = distanta minima dintre c[i] si j
    for(int i = 0; i <= k+1; i++) {
        dist[i][c[i]] = 0;
        priority_queue<pair<int, int> > pq;
        pq.push({0, c[i]});
        while(!pq.empty()) {
            int cur = pq.top().second;
            pq.pop();

            for(auto next: g[cur])
                if(dist[i][next.first] > dist[i][cur]+next.second) {
                    dist[i][next.first] = dist[i][cur]+next.second;
                    pq.push({-dist[i][next.first], next.first});
                }
        }
    }

    vector<vector<int> > dp((1<<(k+2))+5, vector<int> (k+2, 2e9));
    dp[1][0] = 0;
    for(int i = 0; i < (1<<(k+2)); i++)
        for(int j = 0; j <= k+1; j++) {
            if((i&(1<<j)) == 0) continue;
            for(int next = 0; next <= k+1; next++) {
                if(i&(1<<next)) continue;
                dp[i|(1<<next)][next] = min(dp[i|(1<<next)][next], dp[i][j]+dist[j][c[next]]);
                //cout << i << ' ' << j << ' ' << next << '\n';
            }
        }
    fout << dp[(1<<(k+2))-1][k+1];
}