Cod sursa(job #2798539)

Utilizator YusyBossFares Yusuf YusyBoss Data 11 noiembrie 2021 15:23:59
Problema Ubuntzei Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.66 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][KMAX + 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 finish_node) {
  int i, n, c;
  hatz crt, next;

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

    if (crt.node == finish_node)
      return crt.cost;

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

void reset(int n) {
  int i;
  for (i = 1; i <= n; i++)
    f[i] = 0;
  while (!pq.empty())
    pq.pop();
}

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++)
    for (j = 0; j < k; j++) {
      reset(n);
      if (matdist[j][i] == 0)
        matdist[i][j] = bfs(vfriend[i], vfriend[j]);
      else
        matdist[i][j] = matdist[j][i];
    }

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

  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) {
            reset(n);
            dp[mask][last] = minim(dp[mask][last], dp[mask ^ (1 << last)][i] + matdist[last][i]);
          }
        }
      }
    }
  }

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

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