Cod sursa(job #2538811)

Utilizator PetyAlexandru Peticaru Pety Data 5 februarie 2020 10:20:46
Problema Gather Scor 40
Compilator cpp-64 Status done
Runda simulare_miri Marime 2.35 kb
#include <bits/stdc++.h>

using namespace std;

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

struct edge {
  int nod, len, d;
};

vector<edge>G[752];

int a, b, c, d;

int n, k, m, dist[752][(1 << 15)],  gay[752], x, nr[1 << 15];
bool inQ[752][(1 << 15)];

struct Cmp {
  bool operator() (const pair<int, int> &x, const pair<int, int> &y) {
    return dist[x.first][x.second] > dist[y.first][y.second];
  }
};

priority_queue<pair<int, int>, vector<pair<int, int>>, Cmp>pq;

int main()
{
  fin >> k >> n >> m;
  for (int i = 1; i <= k; i++) {
    fin >> x;
    gay[x] = i;
  }
  for (int i = 0; i < (1 << k); i++) {
    int hatz = i, bit = 0;
    while (hatz > 0) {
      bit++;
      hatz = (hatz & (hatz - 1));
    }
    nr[i] = bit;
  }
  for (int i = 1; i <= m; i++) {
    fin >> a >> b >> c >> d;
    G[a].push_back({b, c, d});
    G[b].push_back({a, c, d});
  }
  for (int i = 1; i <= n; i++)
    for (int j = 0; j < (1 << k); j++)
      dist[i][j] = 2e9;
  dist[1][0] = 0;
  if (gay[1])
    dist[1][(1 << (gay[1] - 1))] = 0;
  queue<pair<int, int> >q;
  q.push({1, 0});
  if (gay[1])
    q.push({1, (1 << (gay[1] - 1))});
  inQ[1][0] = 1;
  if (gay[1])
    inQ[1][(1 << (gay[1] - 1))] = 1;
  while (!q.empty()) {
    pair<int, int>p = q.front();
    q.pop();
    inQ[p.first][p.second] = 0;
    if (p.second == (1 << k) - 1)
      continue;
    for (auto it : G[p.first]) {
      int nod = it.nod, l = it.len, d = it.d;
      if (dist[nod][p.second] > dist[p.first][p.second] + l * nr[p.second] + l && d >= nr[p.second]) {
        if (inQ[nod][p.second] == 0) {
          q.push({nod, p.second});
          inQ[nod][p.second] = 1;
        }
        dist[nod][p.second] = dist[p.first][p.second] + l * nr[p.second] + l;
      }
      if (gay[nod] && ((1 << (gay[nod] - 1)) & p.second) == 0) {
        int newM = (p.second | (1 << (gay[nod] - 1)));
        if (dist[nod][newM] > dist[p.first][p.second] + l * nr[p.second] + l && d >= nr[p.second]) {
          if (inQ[nod][newM] == 0) {
            q.push({nod, newM});
            inQ[nod][newM] = 1;
          }
          dist[nod][newM] = dist[p.first][p.second] + l * nr[p.second] + l;
        }
      }
    }
  }
  int ans = 2e9;
  for (int i = 1; i <= n; i++) {
    ans = min(ans, dist[i][(1 << k) - 1]);
  }
  fout << ans;
  return 0;
}