Cod sursa(job #3311534)

Utilizator jumaracosminJumara Cosmin-Mihai jumaracosmin Data 23 septembrie 2025 08:51:19
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.24 kb
#include <bits/stdc++.h>
 
std::ifstream fin("ubuntzei.in");
std::ofstream fout("ubuntzei.out");
 
const int NMAX = 2e3 + 5;
const int KMAX = 17;
const int INF = 1e9;
 
int n, m, k;
std::vector<std::pair<int, int>> graph[NMAX];
int aux_nodes[KMAX];
int aux_dist[KMAX][KMAX];

int dp[KMAX][1 << KMAX];

int main()
{
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
 
    fin >> n >> m >> k;

    aux_nodes[0] = 1;
    for(int i = 1; i <= k; ++i)
    {
        int x;
        fin >> x;
        aux_nodes[i] = x;
     }
    aux_nodes[k + 1] = n;
    k += 2;

    for(int i = 1; i <= m; ++i)
    {
        int x, y, z;
        fin >> x >> y >> z;
        graph[x].push_back({y, z});
        graph[y].push_back({x, z});
    }

    // start = 1, end = n
    
    for(int i = 0; i < k; ++i)
    {
        int start = aux_nodes[i];
        std::vector<int> dist(n + 1, INF);
        dist[start] = 0;
        std::queue<int> q;
        q.push(start);
        
        while(!q.empty())
        {
            int node = q.front();
            q.pop();
            int cost = dist[node];
            
            for(auto adj : graph[node])
                if(cost + adj.second < dist[adj.first])
                {
                    dist[adj.first] = cost + adj.second;
                    q.push(adj.first);
                }
        }

        for(int j = 0; j < k; ++j)
            aux_dist[i][j] = dist[aux_nodes[j]];
    }

    for(int i = 0; i < k; ++i)
        for(int msk = 0; msk < (1 << k); ++msk)
            dp[i][msk] = INF;

    dp[0][1] = 0;  // 1 -> 1 = 0

    for(int msk = 2; msk < (1 << k); ++msk)
    {
        if(!(msk & 1))
            continue;

        for(int j = 0; j < k; ++j)
        {
            if(!(msk & 1))
                continue;

            for(int aux = 0; aux < k; ++aux)
            {
                if(aux == j || !(msk & (1 << aux)))
                    continue;

                // to get to j we can check every AUX -> J in the mask
                dp[j][msk] = std::min(dp[j][msk], dp[aux][msk ^ (1 << j)] + aux_dist[aux][j]);
            }
        }
    }

    int ans = dp[k - 1][(1 << k) - 1];
    fout << ans;

    return 0;
}