Cod sursa(job #2981860)

Utilizator BorodiBorodi Bogdan Borodi Data 18 februarie 2023 20:55:21
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.3 kb
#include <fstream>
#include <queue>
#include <vector>
#include <algorithm>
#include <cstring>
#include <queue>
#include <map>
#define Nmax 2001
#include <vector>
#include <queue>
using namespace std;

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

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

const int oo = 1e7;

VI V[Nmax];
priority_queue< pair <int , int >, vector < pair < int, int > >, greater < pair <int, int > > > Q;
int Dist[16][Nmax], X[16];
int dp[16][1 << 16];
int n, m, k, x, y, c;

void Dijkstra(int v, int order){
     Q.push( { 0, v } );
     Dist[order][v] = 0;

     while(!Q.empty()){
          v = Q.top().second;
          int cost = Q.top().first;

          for(pair <int, int> i : V[v]){
               int vnou = i.second;
               int cnou = Dist[order][v] + i.first;

               if(Dist[order][vnou] > cnou){
                    Q.push({cnou, vnou});
                    Dist[order][vnou] = cnou;
               }
          }

          Q.pop();
     }
}

int main() {

     for(int i = 1; i <= 15; ++i)
          for(int j = 1; j <= 2000; ++j)
               Dist[i][j] = oo;

     fin >> n >> m;
     fin >> k;

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

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

     while(m--){
          fin >> x >> y >> c;

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

     for(int i = 1; i <= k; ++i){
          Dijkstra(X[i], i);
          dp[i][1 << (i - 1)] = Dist[i][1];
     }

     for(int mask = 1; mask <= (1 << k) - 1; ++mask)
        for(int i = 1; i <= k; ++i)
         	if((1 << (i - 1)) & mask)
              for(int j = 1, node = 1; j <= mask, node <= k; j *= 2, ++node)
                   if( (mask & j) && i != node){
                        dp[node][mask] = min(dp[node][mask], dp[i][mask - j] + Dist[node][X[i]]);;
                   }
     if(k == 0){
          Dijkstra(1, 1);
          fout << Dist[1][n];
     }
     else {
        int mask = (1 << k) - 1, mini = oo;

        for(int i = 1; i <= k; ++i){
            if(dp[i][mask] + Dist[i][n] < mini)
                mini = dp[i][mask] + Dist[i][n];
        }

        fout << mini;
    }
}