Cod sursa(job #3277463)

Utilizator andiRTanasescu Andrei-Rares andiR Data 16 februarie 2025 12:22:48
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.93 kb
// Author: Tanasescu Andrei-Rares
/*
     █████╗  ██████╗ ████████╗
    ██╔══██╗ ██╔══██╗╚══██╔══╝
    ███████║ ██████╔╝   ██║   
    ██╔══██║ ██╔══██╗   ██║   
    ██║  ██║ ██║  ██║   ██║   
    ╚═╝  ╚═╝ ╚═╝  ╚═╝   ╚═╝   
*/
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <deque>
#include <iomanip>
#include <vector>
#include <cassert>

#pragma GCC optimize("O3")

#define fi first
#define se second
#define pb push_back
#define pf push_front

using namespace std;

ifstream fin ("ubuntzei.in");
ofstream fout ("ubuntzei.out");

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const ll Nmax=2e3+5, inf=1e9+5, Kmax=15;

int n, m, k;
int kpos[Kmax], dist[Nmax];
int mat[Kmax][Kmax];
int dists[Kmax], distt[Kmax];
int dp[Kmax][1<<Kmax];
vector<pii> ad[Nmax];
priority_queue<pii> pq;

inline void dijkstra(int node){
    for (int i=1; i<=n; i++)
        dist[i]=inf;

    dist[node]=0;

    pq.push({dist[node], node});
    while (!pq.empty()){
        pii crt=pq.top();
        pq.pop();

        int node=crt.se;
        int cost=-crt.fi;

        if (cost>dist[node])
            continue;
        
        for (auto it:ad[node]){
            int newdist=dist[node]+it.se;
            if (newdist<dist[it.fi]){
                dist[it.fi]=newdist;
                pq.push({-newdist, it.fi});
            }
        }
    }
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    fin>>n>>m;
    fin>>k;
    for (int i=0; i<k; i++)
        fin>>kpos[i];
    for (int i=0; i<m; i++){
        int a, b, c;
        fin>>a>>b>>c;
        ad[a].pb({b, c});
        ad[b].pb({a, c});
    }

    if (k==0){
        dijkstra(1);
        fout<<dist[n];
        return 0;
    }

    for (int i=0; i<k; i++){
        dijkstra(kpos[i]);

        for (int j=0; j<k; j++)
            mat[i][j]=dist[kpos[j]];
        dists[i]=dist[1];
        distt[i]=dist[n];
    }

    for (int msk=1; msk<(1<<k); msk++)
        for (int bit=0; bit<k; bit++)
            if ((msk & (1<<bit)) != 0){ // bit e in masca
                int newmsk=msk-(1<<bit);
                if (newmsk==0)
                    dp[bit][msk]=dists[bit];
                else{
                    dp[bit][msk]=inf;
                    for (int newbit=0; newbit<k; newbit++)
                        if ((newmsk & (1<<newbit)) != 0)
                            dp[bit][msk]=min(dp[bit][msk], dp[newbit][newmsk]+mat[newbit][bit]);
                }
            }
    
    int sol=inf;
    for (int bit=0; bit<k; bit++)
        sol=min(sol, dp[bit][(1<<k)-1]+distt[bit]);
    
    fout<<sol<<'\n';

    return 0;
}