Cod sursa(job #2254686)

Utilizator dahaandreiDaha Andrei Codrin dahaandrei Data 5 octombrie 2018 19:24:57
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.14 kb
#include <fstream>
#include <vector>
#include <queue>
#include <string.h>
//de corectat d[] cu d[K[i]] si de regandit ciclul hamilton

using namespace std;

ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");

const int MAXN = 2e3;
const int MAXM = 1e4;
const int MAXK = 15;

int n, m, k, K[MAXK + 1];
vector<pair<int, int> > g[MAXN + 1];
int dp[1 << (MAXK + 2)][MAXK + 2];

class cmp {
public:
  bool operator() (pair<int, int> a, pair<int, int> b) {
    return a.second > b.second;
  }
};

class dijkstra {
public:
  priority_queue<pair<int, int>, vector<pair<int, int> >, cmp> pq;
  pair<int, int> nod;
  int d[MAXN + 1];

  dijkstra(int start = 0) {
    while (pq.size()) pq.pop();
    memset(d, 0x3f3f3f3f, sizeof d);
    nod = make_pair(start, 0);
    d[start] = 0;
    pq.push(nod);
    while (pq.size()) {
      nod = pq.top();
      pq.pop();
      if (nod.second != d[nod.first])
        continue;
      for (auto x : g[nod.first])
        if (d[nod.first] + x.second < d[x.first]) {
          d[x.first] = d[nod.first] + x.second;
          pq.push({x.first, d[x.first]});
        }
    }
  }
}c[MAXK + 2];



int main() {
  in >> n >> m;
  in >> k; for (int i = 1; i <= k; ++ i) in >> K[i];
  K[0] = 1;
  K[k + 1] = n;
  for (int i = 1; i <= m; ++ i) {
    int x, y, z;
    in >> x >> y >> z;
    g[x].push_back({y, z});
    g[y].push_back({x, z});
  }

  for (int i = 1; i <= k; ++ i) {
    c[i] = dijkstra(K[i]);
  }
  c[0] = dijkstra(1);
  c[k + 1] = dijkstra(n);

//  for (int i = 0; i <= k + 1; ++ i) {
//    for (int j = 1; j <= n; ++ j) {
//      out << c[i].d[j] << ' ';
//    }
//    out << '\n';
//  }

  memset(dp, 0x3f3f3f3f, sizeof dp);
  for (int i = 0; i < k + 1; ++ i) dp[1 << i][i + 1] = c[0].d[K[i + 1]];

  for (int i = 1; i < (1 << (k + 1)); ++ i)
    for (int j = 0; j < k + 1; ++ j)
      if (i & 1 << j)
        for (int x = 0; x < k + 1; ++ x)
          if (x != j && i & (1 << x))
            dp[i][j + 1] = min(dp[i][j + 1], dp[i ^ (1 << j)][x + 1] + c[x + 1].d[K[j + 1]]);

  int sol = dp[(1 << (k + 1)) - 1][k + 1];
  out << sol;



  return 0;
}