Cod sursa(job #2261260)

Utilizator Robert_VRVRobert Vadastreanu Robert_VRV Data 16 octombrie 2018 10:07:14
Problema Ubuntzei Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.99 kb
#include <queue>
#include <stdio.h>
#include <vector>

const int MAX_N = 2000;
const int INF = 2000000000;

struct Edge {
  int node;
  int cost;
  bool operator <(const Edge& other) const {
    return this->cost < other.cost;
  }
};
std::vector<Edge> neighbours[1 + MAX_N];
int friends[1 + MAX_N];

int cost[20][1 + MAX_N];

void dijkstra(const int& index) {
  std::priority_queue<Edge> q;
  cost[index][friends[index]] = 0;
  q.push({friends[index], 0});
  while (!q.empty()) {
    Edge edge = q.top();
    q.pop();
    if (edge.cost == cost[index][edge.node]) {
      for (Edge u : neighbours[edge.node]) {
        if (cost[index][u.node] > u.cost + edge.cost) {
          cost[index][u.node] = u.cost + edge.cost;
		  q.push(Edge{u.node, cost[index][u.node]});
        }
      }
    }
  }
}

int dp[1 << 17][20];

int main() {

  freopen("ubuntzei.in", "r", stdin);
  freopen("ubuntzei.out", "w", stdout);

  int n, m;
  scanf("%d%d", &n, &m);
  int k;
  scanf("%d", &k);
  friends[1] = 1;
  friends[k + 2] = n;
  for (int i = 2; i <= k + 1; i++)
	scanf("%d", &friends[i]);
  k += 2;
  for (int i = 1; i <= m; i++) {
	int u, v, price;
    scanf("%d%d%d", &u, &v, &price);
    neighbours[u].push_back(Edge{v, price});
    neighbours[v].push_back(Edge{u, price});
  }
  for (int i = 0; i <= k; i++)
	for (int j = 0; j <= n; j++)
	  cost[i][j] = INF;

  for (int i = 0; i <= k; i++)
	dijkstra(i);

  int max = (1 << k) - 1;
  for (int i = 0; i <= max; i++)
    for (int j = 0; j <= k; j++)
      dp[i][j] = INF;


  dp[1][1] = 0;
  for (int mask = 1; mask <= max; mask++) {
    for (int i = 1; i <= k; i++) {
	  if (!(mask & (1 << (i - 1)))) {
		for (int j = 1; j <= k; j++) {
	      if (mask & (1 << (j - 1))) {
            dp[mask | (1 << (i - 1))][i] = std::min(dp[mask | (1 << (i - 1))][i], dp[mask][j] + cost[j][friends[i]]);
    	  }
		}
	  }
    }
  }

  printf("%d\n", dp[max][k]);

  fclose(stdin);
  fclose(stdout);

  return 0;
}