Cod sursa(job #2576191)

Utilizator popashtefan10Popa Stefan popashtefan10 Data 6 martie 2020 17:47:49
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.07 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#define NMAX 2000
#define KMAX 15
#define DMAX 200000000
#define pii pair<int, int>
#define cost first
#define nod second

using namespace std;

int n, m, k;
int d[NMAX + 5];
int h[(1 << KMAX) + 5][KMAX + 5], dk[KMAX + 5][KMAX + 5];
vector<int> prt;
vector<pii> v[NMAX + 5];
priority_queue<pii, vector<pii>, greater<pii>> pq;

void dijkstra(int start) {
  pii crt, vec;
  for(int i = 1; i <= n; i++)
    d[i] = DMAX + 5;

  pq.push({0, start});
  while(!pq.empty()) {
    while(!pq.empty() && pq.top().cost >= d[pq.top().nod])
      pq.pop();
    if(pq.empty())
      break;

    crt = pq.top();
    pq.pop();
    d[crt.nod] = crt.cost;

    for(int i = 0; i < v[crt.nod].size(); i++) {
      vec = v[crt.nod][i];
      if(crt.cost + vec.cost < d[vec.nod])
        pq.push({crt.cost + vec.cost, vec.nod});
    }
  }
}

void hamilton() {
  int pi, cnod, nbm;

  for(int bm = 1; bm < (1 << k); bm++)
    for(int i = 0; i < k; i++) {
      pi = 1 << i;
      cnod = prt[i];
      if(bm == pi)
        h[bm][i] = d[cnod];
      else if(bm & pi) {
        nbm = bm - pi;
        h[bm][i] = DMAX + 5;
        for(int j = 0; j < k; j++)
          if(j != i && ((1 << j) & nbm) != 0)
            h[bm][i] = min(h[bm][i], h[nbm][j] + dk[j][i]);
      }
    }
}

int main() {
  freopen("ubuntzei.in", "r", stdin);
  freopen("ubuntzei.out", "w", stdout);
  int x, y, z;

  scanf("%d %d", &n, &m);
  scanf("%d", &k);
  for(int i = 1; i <= k; i++) {
    scanf("%d", &x);
    prt.push_back(x);
  }

  for(int i = 1; i <= m; i++) {
    scanf("%d %d %d", &x, &y, &z);
    v[x].push_back({z, y});
    v[y].push_back({z, x});
  }

  for(int i = 0; i < k; i++) {
    dijkstra(prt[i]);
    for(int j = i + 1; j < k; j++)
      dk[j][i] = dk[i][j] = d[prt[j]];
  }
  dijkstra(1);
  hamilton();
  dijkstra(n);

  int ans = DMAX + 5, pk = 1 << k;
  for(int i = 0; i < k; i++)
    ans = min(ans, h[pk - 1][i] + d[prt[i]]);
  printf("%d", (k == 0) ? d[1] : ans);

  return 0;
}