Cod sursa(job #2048714)

Utilizator GoogalAbabei Daniel Googal Data 26 octombrie 2017 15:24:46
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.6 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

const int NMAX = 2000;
const int LMAX = 40000;
const int KMAX = 15;
const int INF = 1 << 30;

struct Edge {
  int to;
  int cost;
};

struct Data {
  int node;
  int cost;

  bool operator< (Data other) const {
    return other.cost < cost;
  }
};

int n, m, k, res;
int src, dest;
int v[1 + KMAX];
int dist[1 + KMAX][1 + LMAX];
int a[1 + LMAX][1 + KMAX];

vector < Edge > g[1 + NMAX];

void addedge(int x, int y, int c) {
  Edge direct = {y, c};
  Edge inverse = {x, c};

  g[x].push_back(direct);
  g[y].push_back(inverse);
}

void dijkstra(int vnode) {
  priority_queue < Data > pq;

  for(int i = 0; i <= n; i++)
    dist[vnode][i] = INF;
  dist[vnode][v[vnode]] = 0;
  pq.push({v[vnode], 0});

  while(!pq.empty()) {
    Data from = pq.top();
    pq.pop();

    if(from.cost <= dist[vnode][from.node]) {
      for(int i = 0; i < g[from.node].size(); i++) {
        Data to;
        to.node = g[from.node][i].to;
        to.cost = g[from.node][i].cost;

        if(from.cost + to.cost < dist[vnode][to.node]) {
          dist[vnode][to.node] = from.cost + to.cost;
          pq.push(to);
        }
      }
    }
  }
}

void solve() {
  for(int i = 0; i <= NMAX; i++)
    for(int j = 0; j <= KMAX; j++)
      a[i][j] = INF;

  for(int m = 1; m < (1 << k); m++) {
    if(! (m & (m - 1))) {
      for(int i = 0; i < k; i++)
        if(m == (1 << i))
          a[m][i] = dist[0][v[i + 1]];
    } else {
      for(int i = 0; i < k; i++) {
        for(int j = 0; j < k; j++) {
          if((m & (1 << i)) != 0 && (m & (1 << j)) != 0)
            a[m][i] = min(a[m][i], a[m - (1 << i)][j] + dist[j + 1][v[i + 1]]);
        }
      }
    }
  }
}

int main()
{
  in >> n >> m >> k;
  src = 1;
  dest = n;

  for(int i = 1; i <= k; i++)
    in >> v[i];

  for(int i = 1; i <= m; i++) {
    int x, y, z;
    in >> x >> y >> z;
    addedge(x, y, z);
  }

  v[0] = src;
  for(int i = 0; i <= k; i++)
    dijkstra(i);

  solve();

  res = INF;
  if(k == 0) {
    res = dist[0][n];
  } else {
    for(int i = 0; i < k; i++)
      res = min(res, a[(1 << k) - 1][i] + dist[i + 1][n]);
  }

  out << res << '\n';
  in.close();
  out.close();
  return 0;
}

  /*
  for(int i = 0; i <= k; i++) {
    cout << v[i] <<": ";
    for(int j = 1; j <= n; j++) {
      if(dist[i][j] != INF)
        cout << dist[i][j] << ' ';
      else
        cout << "-1 ";
    }
    cout << '\n';
  }
  */