Cod sursa(job #2983374)

Utilizator gabriel10tm@gmail.comGabriel Marian [email protected] Data 22 februarie 2023 12:13:31
Problema Ubuntzei Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.09 kb
#include <bits/stdc++.h>
using namespace std;
// everything is 0 indexed
const int kmx = 17;
const int mskmx = 1<<kmx;
const int nmx = 2e3 + 5;
const int inf = 1e7;
int n;
#define ll int64_t
vector<array<int,2>> ad[nmx];
vector<int> kv;
ll dp[mskmx][kmx]; // cel mai scurt drum de la 0 la n trecand prin nodurile din mask
// indexul bitilor este acelasi cu cel al nodurilor din kv
#if 1
#define cin fin
#define cout fout
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
#endif // 1
vector<vector<ll>> g(kmx,vector<ll>(kmx));

void dijk(int st,int idx){
    vector<ll> d(n,inf);
    set<array<ll,2>> s;
    s.insert({0,st});
    d[st] = 0;
    while(s.size()){
        auto it = s.begin();
        int nd = (*it)[1];
        s.erase(it);
        for(array<int,2> edg : ad[nd]){
            int to = edg[0], w = edg[1];
            if(d[to] > d[nd] + w){
                s.erase({d[to],to});
                d[to] = d[nd] + w;
                s.insert({d[to],to});
            }
        }
    }
    for(int i=0;i<kv.size();i++){
        g[idx][i] = d[kv[i]];
    }
}

int main(){
    for(int i=0;i<kmx;i++)
        for(int j=0;j<kmx;j++)
            g[i][j] = inf;
    int m,k;
    cin >> n >> m >> k;
    kv.push_back(0);
    for(int i=0;i<k;i++){
        int x;
        cin >> x;
        x--;
        kv.push_back(x);
    }
    kv.push_back(n-1);

    while(m--){
        int u,v,w;
        cin >> u >> v >> w;
        u--,v--;
        ad[u].push_back({v,w});
    }

    for(int i=0;i<kv.size();i++)
        dijk(kv[i],i);

    for(int i=0;i<mskmx;i++)
        for(int j=0;j<kmx;j++)
            dp[i][j] = inf;

    dp[1][0] = 0;
    int nsz = kv.size();
    int mskn = 1 << nsz;
    for(int msk=1;msk<mskn;msk++){
        for(int i=0;i<nsz;i++){
            if(msk&(1<<i)){
                for(int j=0;j<nsz;j++){
                    dp[msk][i] = min(dp[msk][i],dp[msk^(1<<i)][j]+g[j][i]);
                    dp[msk][i] = min(dp[msk][i],dp[msk][j]+g[j][i]);
                }
            }
        }
    }
    cout << dp[mskn-1][nsz-1];
}