Cod sursa(job #1900987)

Utilizator AndreiFlorescuAndrei Florescu AndreiFlorescu Data 3 martie 2017 18:10:21
Problema Ubuntzei Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.46 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;

struct cell {
  int vec;
  int cost;
};

struct minHeap {
  bool operator () (cell a, cell b) {
    return a.cost < b.cost;
  }
};

int INF = 0x7fffffff;
int aux = 0x3f3f3f3f;

vector<cell> graf[2001];
priority_queue<cell, vector<cell>, minHeap> heap;
int distDij[2002];
int traseu[17];
int dist[17][17];
int dinam[131072][17];
int n;

int minim (int a, int b) {
  if (a < b) {
    return a;
  }
  return b;
}

void reinitDij () {
  for (int i = 0; i <= n; i++) {
    distDij[i] = INF;
  }
}

void initDinam (int config, int k) {
  for (int i = 1; i < config; i++) {
    for (int j = 0; j <= k; j++) {
      dinam[i][j] = INF;
    }
  }
}

void dijkstra (int start) {
  //reinitDij();
  memset(distDij, aux, sizeof(distDij));
  distDij[start] = 0;
  heap.push((cell){start, 0});
  while (!heap.empty()) {
    cell act = heap.top();
    heap.pop();
    if (act.cost == distDij[act.vec]) {
      for (vector<cell>::iterator it = graf[act.vec].begin(); it != graf[act.vec].end(); it++) {
        if (distDij[act.vec] + it->cost < distDij[it->vec]) {
          distDij[it->vec] = distDij[act.vec] + it->cost;
          heap.push((cell){it->vec, distDij[it->vec]});
        }
      }
    }
  }
}

int main() {
    ifstream file_in ("ubuntzei.in");
    ofstream file_out ("ubuntzei.out");

    int m, k;
    int u, v, cost;
    int i, j;

    file_in >> n >> m;
    file_in >> k;
    for (i = 1; i <= k; i++) {
      file_in >> traseu[i];
    }
    for (i = 0; i < m; i++) {
      file_in >> u >> v >> cost;
      graf[u].push_back((cell){v, cost});
      graf[v].push_back((cell){u, cost});
    }
    traseu[0] = 1;
    traseu[k + 1] = n;

    for (i = 0; i <= k + 1; i++) {
      dijkstra(traseu[i]);
      for (j = 0; j <= k + 1; j++) {
        dist[i][j] = distDij[traseu[j]];
      }
    }

    int config = 1 << (k + 2);
    initDinam(config, k + 1);

    for (int pas = 1; pas < config; pas++) {
      for (i = 0; i <= k + 1; i++) {
        if (pas & (1 << i)) {
          for (j = 0; j <= k + 1; j++) {
            if (pas & (1 << j)) {
              dinam[pas][i] = minim(dinam[pas][i],
                                    dinam[pas ^ (1 << i)][j] + dist[j][i]);
            }
          }
        }
      }
    }

    file_out << dinam[config - 1][k + 1] << "\n";

    return 0;
}