Cod sursa(job #2714985)

Utilizator Al3ks1002Alex Cociorva Al3ks1002 Data 2 martie 2021 19:53:38
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.07 kb
#include <bitset>
#include <fstream>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

const int NMAX = 2005;
const int inf = (1 << 30) - 1;

#define pii pair<int, int>

int dist[17][17], drum[NMAX];
struct comp {
  bool operator()(int a, int b) { return drum[a] > drum[b]; }
};

vector<pair<int, int>> v[NMAX];
priority_queue<pii, vector<pii>, greater<pii>> pq;

int dp[1 << 17][17];
int n, k;
vector<int> special;

bitset<NMAX> viz;

void dijkstra(int x) {
  pq.push({0, x});
  drum[x] = 0;
  while (!pq.empty()) {
    x = pq.top().second;
    pq.pop();
    if (viz[x] == 1)
      continue;
    else
      viz[x] = 1;
    for (auto el : v[x]) {
      int new_node = el.first;
      int new_cost = drum[x] + el.second;
      if (new_cost < drum[new_node]) {
        drum[new_node] = new_cost;
        pq.push({new_cost, new_node});
      }
    }
  }
}

int main() {
  ifstream cin("ubuntzei.in");
  ofstream cout("ubuntzei.out");
  int n, m, x, y, c, i, j;

  cin >> n >> m >> k;
  special.push_back(1);
  for (i = 1; i <= k; i++) {
    cin >> x;
    special.push_back(x);
  }
  special.push_back(n);
  k += 2;
  for (i = 1; i <= m; i++) {
    cin >> x >> y >> c;
    v[x].push_back({y, c});
    v[y].push_back({x, c});
  }

  for (i = 0; i < k; i++) {
    for (j = 1; j <= n; j++) {
      drum[j] = inf;
    }
    viz.reset();
    dijkstra(special[i]);
    for (j = 0; j < k; j++) {
      dist[i][j] = drum[special[j]];
    }
  }

  /* for (i = 0; i < k; i++) { */
  /*   for (j = 0; j < k; j++) { */
  /*     cout << dist[i][j] << ' '; */
  /*   } */
  /*   cout << endl; */
  /* } */

  for (i = 0; i < (1 << k); i++) {
    for (j = 0; j < k; j++) {
      dp[i][j] = inf;
    }
  }

  int mask;

  dp[1][0] = 0;
  for (mask = 0; mask < (1 << k); mask++) {
    for (i = 1; i < k; i++) {
      if ((1 << i) & mask) {
        for (j = 0; j < k; j++) {
          if (dist[i][j]) {
            int c = dist[i][j];
            dp[mask][i] = min(dp[mask][i], dp[mask - (1 << i)][j] + c);
          }
        }
      }
    }
  }

  int rez = inf;

  cout << dp[(1 << k) - 1][k - 1];

  return 0;
}