Cod sursa(job #2716921)

Utilizator Dobricean_IoanDobricean Ionut Dobricean_Ioan Data 5 martie 2021 22:32:46
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.18 kb
#include <bits/stdc++.h>
 
using namespace std;
 
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
 
const int nmax = 2005, mmax = 10005, kmax = 16, inf = (1 << 30);
int n, m, k, c[kmax], dp[16][nmax], dp2[(1 << kmax)][kmax];
vector <pair <int, int> > G[nmax];
 
struct state{
    int nod, cost;
    bool operator < (const state &a) const{
        return cost > a.cost;
    }
};
 
void Dijkstra(int index){
    for (int i = 0; i <= n; ++i){
        dp[index][i] = inf;
    }
    int startNode = 1;
    if (index != 0){
        startNode = c[index];
    }
    priority_queue <state> pq;
    pq.push({startNode, 0});
    dp[index][startNode] = 0;
    while (!pq.empty()){
        state s = pq.top();
        pq.pop();
        for (auto it : G[s.nod]){
            int newCost = it.second + s.cost;
            if (newCost < dp[index][it.first]){
                dp[index][it.first] = newCost;
                pq.push({it.first, newCost});
            }
        }
    }
}
 
int main(){
    fin >> n >> m >> k;
    for (int i = 1; i <= k; ++i){
        fin >> c[i];
    }
    for (int i = 1; i <= m; ++i){
        int x, y, z;
        fin >> x >> y >> z;
        G[x].push_back({y, z});
        G[y].push_back({x, z});
    }
 
    Dijkstra(0);
    for (int i = 1; i <= k; ++i){
        Dijkstra(i);
    }
    for (int i = 0; i < (1 << k); ++i){
        for (int j = 0; j < k; ++j){
            dp2[i][j] = inf;
        }
    }
    for (int i = 0; i < k; ++i){
        dp2[(1 << i)][i] = dp[0][c[i + 1]];
    }
    for (int i = 1; i < (1 << k); ++i){
        for (int j = 0; j < k; ++j){
            if ((i >> j) & 1){
                for (int j2 = 0; j2 < k; ++j2){
                    if (((i >> j2) & 1) == 0){
                        dp2[(i | (1 << j2))][j2] = min(dp2[(i | (1 << j2))][j2], dp2[i][j] + dp[j + 1][c[j2  + 1]]);
                    }
                }
            }
        }
    }
    int minim = inf;
    if (k){
        for (int i = 0; i < k; ++i){
            minim = min(minim, dp2[((1 << k) - 1)][i] + dp[i + 1][n]);
        }
    }
    else{
        minim = dp[0][n];
    }
    fout << minim;
    return 0;
}