Cod sursa(job #2853304)

Utilizator BorodiBorodi Bogdan Borodi Data 20 februarie 2022 10:22:00
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.14 kb
#include <fstream>
#include <queue>
#include <vector>
#include <algorithm>
#define Nmax 2001
using namespace std;

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

typedef vector < pair <int , int > > VIP;

VIP V[Nmax * 5];
int n, m, k, x, y, c;
int X[Nmax];
int D[Nmax / 100][Nmax];
const int oo = 1 << 28;
priority_queue < pair< int , int >, VIP, greater < pair < int , int > > > Q;


int dp[17][1 << 17];

void Dijkstra(int level, int vertex){
    D[level][vertex] = 0;
    Q.push( { 0, vertex } );

    while(!Q.empty()){
        vertex = Q.top().second;

        for(pair <int , int> new_vertex : V[vertex]){
            int new_v = new_vertex.second;
            int new_c = new_vertex.first;

            if(D[level][new_v] > D[level][vertex] + new_c){
                D[level][new_v] = D[level][vertex] + new_c;
                Q.push( { D[level][new_v], new_v } );
            }
        }

        Q.pop();
    }
}

int main() {   
    fin >> n >> m;

    fin >> k;

    for(int i = 1; i <= k; ++i)
        fin >> X[i];

    for(int i = 1; i <= m; ++i){
        fin >> x >> y >> c;

        V[x].push_back({c,y});
        V[y].push_back({c,x});
    }

    for(int i = 0; i <= k; ++i)
        for(int j = 0; j <= n; ++j)
            D[i][j] = oo;

    Dijkstra(0, 1);

    for(int i = 1; i <= k; ++i)
        Dijkstra(i, X[i]);

    for(int i = 0; i <= k; ++i)
        for(int j = 0; j < (1 << k); ++j)
            dp[i][j] = oo;

    for(int i = 1; i <= k; ++i)
        dp[i][1 << (i - 1)] = D[0][X[i]];

    for(int mask = 1; mask < (1 << k); ++mask)
        for(int city = 1; city <= k; ++city)
            if(mask & ( 1 << (city - 1) ) )
                for(int s_city = 1; s_city <= k; ++s_city){
                    int aux = (1 << (s_city - 1));

                    if( ( mask & aux) && s_city != city)
                        dp[city][mask] = min(dp[city][mask], dp[city][mask - aux] + D[city][X[s_city]]);
                }
    
    int mini = oo;
 
    for(int i = 1; i <= k; ++i)
        mini = min(mini, dp[i][(1 << k) - 1] + D[i][n]);

    fout << mini;

    return 0;
}