Cod sursa(job #2984321)

Utilizator AztecaVlad Tutunaru 2 Azteca Data 23 februarie 2023 22:14:31
Problema Ubuntzei Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.08 kb
#include <bits/stdc++.h>

using namespace std;

bool home = 1;
typedef long long ll;
typedef long double ld;
#define int ll
signed realMain();

signed main() {
#ifdef ONLINE_JUDGE
  home = 0
#endif
  if (home) {
    ///freopen ("tony_stark", "r", stdin);
    freopen ("ubuntzei.in", "r", stdin);
    freopen ("ubuntzei.out", "w", stdout);
  } else {
    ios_base::sync_with_stdio(0); cin.tie(0);
  }
  realMain();
}

const int N = (int) 2e3 + 7;
const int K = 15;
const int INF = (int) 2e9;
int c[K], dp[N][1 << K], vis[N], dist[K][N];
vector<pair<int, int>> g[N];
int n, m, k;

void dijkstra(int start, int ind) {
  for (int i = 1; i <= n; i++) {
    dist[ind][i] = INF;
    vis[i] = false;
  }
  priority_queue<pair<int, int>> pq;
  pq.push({0, start});
  dist[ind][start] = 0;
  while (!pq.empty()) {
    int u = pq.top().second;
    pq.pop();
    if (vis[u]) continue;
    vis[u] = true;
    for (auto &v : g[u]) {
      if (dist[ind][u] + v.second < dist[ind][v.first]) {
        dist[ind][v.first] = dist[ind][u] + v.second;
        pq.push({-dist[ind][v.first], v.first});
      }
    }
  }
}

signed realMain() {
  cin >> n >> m >> k;
  for (int i = 0; i < k; i++) {
    cin >> c[i];
  }
  for (int i = 1; i <= m; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    g[a].push_back({b, c});
    g[b].push_back({a, c});
  }
  for (int i = 0; i < k; i++) {
    dijkstra(c[i], i);
  }
  for (int i = 0; i < k; i++) {
    for (int mask = 0; mask < (1 << k); mask++) {
      dp[i][mask] = INF;
    }
  }
  for (int i = 0; i < k; i++) {
    dp[i][(1 << i)] = dist[i][1];
  }

  for (int mask = 0; mask < (1 << k); mask++) {
    for (int i = 0; i < k; i++) {
      if (mask & (1 << i)) {
        for (int j = 0; j < k; j++) {
          if (i != j && (mask & (1 << j))) {
            dp[i][mask] = min(dp[i][mask], dp[j][mask ^ (1 << i)] + dist[j][c[i]]);
          }
        }
      }
    }
  }

  ll ret = INF;
  for (int i = 0; i < k; i++) {
    ret = min(ret, dp[i][(1 << k) - 1] + dist[i][n]);
  }
  cout << ret << "\n";
  return 0;
}