Cod sursa(job #2028943)

Utilizator Stefan_RaduStefan Radu Stefan_Radu Data 28 septembrie 2017 21:05:35
Problema Ubuntzei Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.36 kb
#include <fstream>
#include <queue>
#include <vector>
#include <functional>

using namespace std;

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

const int INF = 2e9;
const int MAX_MASK = (1 << 15) + 17;

priority_queue < pair < int, int >, 
  vector < pair < int, int > >,
  greater < pair < int, int > > > heap;

void dijkstra(int nod, int index, vector < vector < int > > &dist,
  vector < vector < pair < int, int > > > &gr) {

  heap.push({0, nod});
  dist[index][nod] = 0;

  while (not heap.empty()) {
    auto cur_dist = heap.top().first;
    auto cur_node = heap.top().second;
    heap.pop();

    if (cur_dist != dist[index][cur_node]) {
      continue;
    }

    for (auto x : gr[cur_node]) {

      int dist_to_neigh = x.first + cur_dist;
      int neigh_node = x.second;

      if (dist_to_neigh < dist[index][neigh_node]) {
        dist[index][neigh_node] = dist_to_neigh;
        heap.push({dist_to_neigh, neigh_node});
      }
    }
  }
}

int main(int argc, char const *argv[]) {
  
  int n, m;
  cin >> n >> m;
  int k;
  cin >> k;

  vector < int > town(k + 1);
  for (int i = 0; i < k; i ++) {
    cin >> town[i];
  }

  vector < vector < pair < int, int > > > gr(n + 1);

  for (int i = 1; i <= m; i ++) {
    int x, y, cost;

    cin >> x >> y >> cost;
    gr[x].push_back({cost, y});
    gr[y].push_back({cost, x});
  }

  vector < vector < int > > dist(k + 1, vector < int > (n + 1, INF));
  for (int i = 0; i < k; i ++) {
    dijkstra(town[i], i, dist, gr);
  }

  vector < vector < int > > dp(MAX_MASK, vector < int > (k + 1, INF));
  for (int i = 0; i < k; i ++) {
    int bit = (1 << i);
    dp[bit][i] = dist[i][1];
  }

  int sol = INF;
  int max_val_mask = (1 << k) - 1;
  for (int mask = 1; mask <= max_val_mask; mask ++) {
    for (int last_town = 0; last_town < k; last_town ++) {
      if (dp[mask][last_town] == INF) {
        continue;
      }

      if (mask == max_val_mask) {
        int last_dist = dist[last_town][n];
        sol = min(sol, dp[mask][last_town] + last_dist);
        continue;
      }
      
      for (int bit = 0; bit < k; bit ++) {
        int pow_bit = (1 << bit);
/*        if ((pow_bit & mask) != 0) {
          continue;
        }*/

        int next_mask = mask ^ pow_bit;
        dp[next_mask][bit] = min(dp[next_mask][bit], 
          dp[mask][last_town] + dist[bit][town[last_town]]);
      }
    }
  }

  cout << sol << '\n';
}