Cod sursa(job #3334406)

Utilizator tudorbeloiuLuka Modric tudorbeloiu Data 17 ianuarie 2026 13:49:33
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.26 kb
#include <fstream>
#include <vector>
#include <queue>
#include <unordered_map>

using namespace std;

ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");

const int INF = 1e9;

int n,m,k,x,y,c;
vector<int> ck;

void dijkstra(int startNode, const vector<vector<pair<int,int>>>& adj, vector<int>& dist){

    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
    pq.push(make_pair(0, startNode));
    dist[startNode] = 0;

    while(!pq.empty()){
        auto [wt, nod] = pq.top();
        pq.pop();

        if(wt > dist[nod])
            continue;

        for(auto& [neigh, cost]: adj[nod]){
            if(dist[neigh] > cost + dist[nod]){
                dist[neigh] = cost + dist[nod];
                pq.push(make_pair(dist[neigh], neigh));
            }
        }
    }
}

int main(){

    f >> n >> m;
    f >> k;

    vector<vector<pair<int,int>>> adj(n+1);
    vector<vector<pair<int,int>>> adj_compressed(k+2);
    vector<int> dist(n+1,INF);

    ck.push_back(1);
    for(int i=1; i<=k; i++){
        f >> x;
        ck.push_back(x);
    }
    ck.push_back(n);

    for(int i=1; i<=m; i++){
        f >> x >> y >> c;
        adj[x].push_back(make_pair(y,c));
        adj[y].push_back(make_pair(x,c));
    }


    for(int i=0; i<k+2; i++){
        dist.assign(n+1, INF);
        dijkstra(ck[i], adj, dist);

        for(int j=i+1; j<k+2; j++){
            int min_distance = dist[ck[j]];

            adj_compressed[i].push_back(make_pair(j, min_distance));
            adj_compressed[j].push_back(make_pair(i, min_distance));
        }
    }

    vector<vector<int>>distBM(1 << k+2, vector<int>(k+2, INF));
    distBM[1][0] = 0;

    for(int mask = 1; mask < (1 << (k+2)); mask++){
        for(int i=0; i<k+2; i++){

            if(distBM[mask][i] != INF){

                for(auto& [neigh, cost]: adj_compressed[i]){

                    if(!((mask >> neigh) & 1)){
                        int newMask = mask | (1 << neigh);

                        if(distBM[newMask][neigh] > cost + distBM[mask][i]){
                            distBM[newMask][neigh] = cost + distBM[mask][i];
                        }
                    }
                }
            }
        }
    }

    int finalMask = (1 << k+2) -1;
    g << distBM[finalMask][k+1];

    
    return 0;
}