Cod sursa(job #2799042)

Utilizator YusyBossFares Yusuf YusyBoss Data 12 noiembrie 2021 11:33:31
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.5 kb
#include <fstream>
#include <vector>
#include <queue>
#define NMAX 2000
#define KMAX 15
#define MASKMAX (1 << 15)
#define INF 2100000000

using namespace std;

ifstream cin ("ubuntzei.in");
ofstream cout ("ubuntzei.out");

struct hatz {
  int node;
  int cost;

  bool operator < (const hatz &A) const {
    return cost > A.cost;
  }
};

int vfriend[KMAX + 1];
int matdist[KMAX + 1][NMAX + 1];
int dp[MASKMAX][KMAX + 1];
bool f[NMAX + 1];
priority_queue <hatz> pq;
vector <hatz> vnext[NMAX + 1];

static inline int minim(int a, int b) {
  return a < b ? a : b;
}

int bfs(int startnode, int n, int vdist[]) {
  int i, nnext, c;
  hatz crt, next;

  for (i = 1; i <= n; i++) {
    f[i] = 0;
    vdist[i] = -1;
  }

  pq.push({startnode, 0});
  while (!pq.empty()) {
    crt = pq.top();
    pq.pop();

    if (f[crt.node] == 0) {
      f[crt.node] = 1;
      vdist[crt.node] = crt.cost;
      nnext = vnext[crt.node].size();
      for (i = 0; i < nnext; i++) {
        next = vnext[crt.node][i];
        if (vdist[next.node] == -1 || vdist[crt.node] + next.cost < vdist[next.node]) {
          pq.push({next.node, crt.cost + next.cost});
          vdist[next.node] = vdist[crt.node] + next.cost;
        }
      }
    }
  }
}

int getnr() {
  int nr;
  char ch;

  while (!isdigit(ch))
    ch = cin.get();

  nr = 0;
  while (isdigit(ch)) {
    nr = nr * 10 + ch - '0';
    ch = cin.get();
  }

  return nr;
}

int main() {
  int n, m, k, a, b, c, i, j, mask, last, sol;
  n = getnr();
  m = getnr();
  k = getnr();

  for (i = 0; i < k; i++)
    vfriend[i] = getnr();
  for (i = 0; i < m; i++) {
    a = getnr();
    b = getnr();
    c = getnr();
    vnext[a].push_back({b, c});
    vnext[b].push_back({a, c});
  }

  for (i = 0; i < k; i++) {
    bfs(vfriend[i], n, matdist[i]);
    dp[(1 << i)][i] = matdist[i][1];
  }

  for (mask = 0; mask < (1 << k); mask++) {
    for (last = 0; last < k; last++) {
      if ((mask & (1 << last)) > 0 && dp[mask][last] == 0) {
        dp[mask][last] = INF;
        for (i = 0; i < k; i++) {
          if (i != last && (mask & (1 << i)) > 0)
            dp[mask][last] = minim(dp[mask][last], dp[mask ^ (1 << last)][i] + matdist[last][vfriend[i]]);
        }
      }
    }
  }

  sol = INF;
  for (last = 0; last < k; last++) {
    sol = minim(sol, dp[(1 << k) - 1][last] + matdist[last][n]);
  }

  if (k == 0) {
    bfs(1, n, matdist[0]);
    sol = matdist[0][n];
  }
  cout << sol;
  return 0;
}