Cod sursa(job #2856178)

Utilizator Albert_GAlbert G Albert_G Data 23 februarie 2022 15:32:38
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.3 kb
#include <fstream>
#include <queue>
#include <vector>
#include <limits>
#include <algorithm>

std::ifstream in("ubuntzei.in");
std::ofstream out("ubuntzei.out");

struct branch{
    int node, cost;
};

constexpr int N = 2001;
constexpr int K = 15;
std::vector<branch> g[N];
std::vector<int> path;
int cost[K+2][K+2], dp[1 << (K+2)][K], dist[N], n, m, k;
bool selected[N];

void dijkstra(int start){
    std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, std::greater<std::pair<int, int>>> q;
    std::fill(dist + 1, dist + 1 + n, std::numeric_limits<int>::max());
    std::fill(selected + 1, selected + 1 + n, false);
    dist[start] = 0;
    q.push({0, start});
    while(!q.empty()){
        int parent = q.top().second;
        q.pop();
        if(selected[parent]) continue;
        selected[parent] = true;
        for(auto branch : g[parent]){
            int child = branch.node;
            int cost = branch.cost;
            if(dist[parent] + cost < dist[child]){
                dist[child] = dist[parent] + cost;
                q.push({dist[child], child});
            }
        }
    }
}

int hamilton(){
    int lim = 1 << k;
    for(int mask=1; mask<lim; ++mask)
        std::fill(dp[mask], dp[mask] + k, std::numeric_limits<int>::max());
    dp[1][0] = 0;
    for(int mask=1; mask<lim; mask += 2){
        for(int parent=0; parent<k; ++parent){
            if( !((1 << parent) & mask) || dp[mask][parent]==std::numeric_limits<int>::max()) continue;
            for(int child=1; child<k; ++child){
                int newMask = mask | (1 << child);
                dp[newMask][child] = std::min(dp[mask][parent] + cost[parent][child], dp[newMask][child]);
            }
        }
    }
    return dp[(1 << k) - 1][k-1];
}

int main(){
    in >> n >> m >> k;
    path.push_back(1);
    for(int i=0; i<k; ++i){
        int u;
        in >> u;
        path.push_back(u);
    }
    k += 2;
    path.push_back(n);
    for(int i=0; i<m; ++i){
        int u, v, c;
        in >> u >> v >> c;
        g[u].push_back({v, c});
        g[v].push_back({u, c});
    }
    for(int i=0; i<k; ++i){
        dijkstra(path[i]);
        for(int j=0; j<k; ++j){
            cost[i][j] = cost[j][i] = dist[path[j]];
    }
    }
    out << hamilton();
}