Cod sursa(job #2538891)

Utilizator PetyAlexandru Peticaru Pety Data 5 februarie 2020 12:14:00
Problema Gather Scor 10
Compilator cpp-64 Status done
Runda simulare_miri Marime 2.45 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 k, n, m, x, dist[752];
int d[16][16][16];

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

int a, b, c,yeet;

bool inQ[752];
int dp[(1 << 15)][16];

int main()
{
  fin >> k >> n >> m;
  vector<int>nod;
  nod.push_back(1);
  for (int i = 1; i <= k; i++) {
    fin >> x;
    nod.push_back(x);
  }
  for (int i = 1; i <= m; i++) {
    fin >> a >> b >> c >> yeet;
    G[a].push_back({b, c, yeet});
    G[b].push_back({a, c, yeet});
  }
  for (int i = 0; i <= k; i++)
    for (int j = 0; j <= k; j++)
      for (int t = 0; t <= k; t++)
        d[i][j][t] = -1;
  for (int i = 0; i <= k; i++) {
    for (int j = 0; j <= k; j++) {
      memset(inQ, 0, sizeof(inQ));
      priority_queue<int, vector<int>, Cmp>q;
      q.push(nod[i]);
      inQ[nod[i]] = 1;
      for (int t = 1; t <= n; t++)
        dist[t] = 2e9;
      dist[nod[i]] = 0;
      while (!q.empty()) {
        int x = q.top();
        q.pop();
        inQ[x] = 0;
        for (auto it : G[x]) {
          if (dist[it.nod] > dist[x] + it.len && it.d >= j) {
            dist[it.nod] = dist[x] + it.len * (j + 1);
            if (inQ[it.nod] == 0) {
              inQ[it.nod] = 1;
              q.push(it.nod);
            }
          }
        }
      }
      for (int t = 0; t <= k; t++) {
        if (dist[nod[t]] != 2e9)
        d[i][t][j] = dist[nod[t]];
      }
    }
  }
  k++;
  for (int i = 0; i < (1 << k); i++)
    for (int j = 0; j < k; j++)
      dp[i][j] = -1;
  dp[1][0] = 0;
  for (int i = 1; i < (1 << k); i++) {
    if (!(i & 1))
    continue;
    int nr = 0;
    for (int j = 1; j < k; j++)
      if (i & (1 << j))
        nr++;
    for (int j = 0; j < k; j++)
      if (dp[i][j] != -1)
      for (int t = 1; t < k; t++) {
        if (i & (1 << t))
          continue;
        if (dp[(i | (1 << t))][t] == -1 && d[j][t][nr] != -1) {
          dp[(i | (1 << t))][t] = dp[i][j] + d[j][t][nr];
        }
        else if (dp[(i | (1 << t))][t] > dp[i][j] + d[j][t][nr] && d[j][t][nr] != -1)
          dp[(i | (1 << t))][t] > dp[i][j] + d[j][t][nr];
      }
  }
  int ans = 1e9;
  for (int i = 0; i < k; i++)
    if (dp[(1 << k) - 1][i] != -1)
    ans = min(ans, dp[(1 << k) - 1][i]);
  fout << ans;
  return 0;
}