Cod sursa(job #2374392)

Utilizator cella.florescuCella Florescu cella.florescu Data 7 martie 2019 18:22:23
Problema Ubuntzei Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.87 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 2e3;
const int MAXK = 15;
const int INF = 0x3f3f3f3f;

struct PQNode {
  int node, cost;
  bool operator < (const PQNode& other) const {
    return cost > other.cost;
  }
};

int dp[MAXK + 2][1 << MAXK], ubu[MAXK + 2], dist[MAXN + 1], adj[MAXK + 2][MAXK + 2];
vector < pair < int, int > > g[MAXN + 1];
priority_queue < PQNode > pq;

int main()
{
    int n, m, k;
    ifstream fin("ubuntzei.in");
    fin >> n >> m >> k;
    for (int i = 0; i < k; ++i)
      fin >> ubu[i];
    for (int i = 0; i < m; ++i) {
      int x, y, z;
      fin >> x >> y >> z;
      g[x].push_back({y, z});
      g[y].push_back({x, z});
    }
    fin.close();
    ubu[k] = 1;
    ubu[k + 1] = n;
    for (int i = 0; i < k + 2; ++i) {
      memset(dist, INF, sizeof dist);
      dist[ubu[i]] = 0;
      pq.push({ubu[i], 0});
      while (pq.empty() == false) {
        int node = pq.top().node, cost = pq.top().cost;
        pq.pop();
        if (cost == dist[node])
          for (auto it : g[node])
            if (cost + it.second < dist[it.first]) {
              dist[it.first] = cost + it.second;
              pq.push({it.first, dist[it.first]});
            }
      }
      for (int j = 0; j < k + 2; ++j)
        adj[i][j] = dist[ubu[j]];
    }
    memset(dp, INF, sizeof dp);
    for (int i = 0; i < k; ++i)
      dp[i][1 << i] = adj[k][i];
    for (int conf = 1; conf < (1 << k); ++conf)
      for (int node = 0; node < k; ++node)
        if ((1 << node) & conf)
          for (int lst = 0; lst < k; ++lst)
            if (lst != node && (1 << lst) & conf)
              dp[node][conf] = min(dp[node][conf], adj[lst][node] + dp[lst][conf ^ (1 << node)]);
    int ans = INT_MAX;
    for (int i = 0; i < k; ++i)
      ans = min(ans, dp[i][(1 << k) - 1] + adj[i][k + 1]);
    ofstream fout("ubuntzei.out");
    fout << ans << '\n';
    fout.close();
    return 0;
}