Cod sursa(job #2519807)

Utilizator popashtefan10Popa Stefan popashtefan10 Data 8 ianuarie 2020 14:23:54
Problema Ubuntzei Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.29 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>

#define NMAX 2000
#define MMAX 10000
#define pii pair<int, int>

using namespace std;

int n, m, k, ltot;
int prieten[NMAX + 5], calc[NMAX + 5], dmin[NMAX + 5];
int noduri[20];
int dp[(1 << 16) + 2][20];
vector<pii> v[NMAX + 5], nv[NMAX + 5];
priority_queue<pii, vector<pii>, greater<pii>> pq;

void dijkstra(int start) {
  for(int i = 1; i <= n; i++)
    dmin[i] = MMAX * 100000 + 5;

  pq.push({0, start});
  while(!pq.empty()) {
    while(!pq.empty() && dmin[pq.top().second] <= pq.top().first)
      pq.pop();
    if(pq.empty())
      break;
    pii crt = pq.top();
    pq.pop();
    dmin[crt.second] = crt.first;
    if(prieten[crt.second] && crt.second != start)
      nv[prieten[start]].push_back({prieten[crt.second], crt.first});

    for(pii x: v[crt.second])
      if(crt.first + x.second < dmin[x.first])
        pq.push({crt.first + x.second, x.first});
  }
}

int main() {
  freopen("ubuntzei.in", "r", stdin);
  freopen("ubuntzei.out", "w", stdout);
  int x, y, l, crt, bm;

  scanf("%d %d %d ", &n, &m, &k);
  for(int i = 1; i <= k; i++) {
    scanf("%d", &x);
    prieten[x] = i;
    noduri[i] = x;
  }

  for(int i = 1; i <= m; i++) {
    scanf("%d %d %d", &x, &y, &l);
    v[x].push_back({y, l});
    v[y].push_back({x, l});
  }

  prieten[1] = 0;
  dijkstra(1);
  noduri[0] = 1;
  for(int i = 1; i <= k; i++)
    dijkstra(noduri[i]);

//  for(int i = 0; i <= k; i++) {
//    printf("nod:%d vecini: ", noduri[i]);
//    for(pii vecin: nv[i])
//      printf("nod:%d distanta:%d ", vecin.first, vecin.second);
//    printf("\n");
//  }

  for(bm = 1; bm < (1 << (k + 1)); bm++)
    for(int i = 0; i <= k; i++)
      dp[bm][i] = MMAX * 100000 + 5;
  dp[1][0] = 0;

  for(bm = 1; bm < (1 << (k + 1)); bm++)
    for(int i = 0; i <= k; i++)
      for(pii vecin: nv[i]) {
        int j = vecin.first, cost = vecin.second;

        if(((1 << j) & bm) == 0) {
          int nbm = bm | (1 << j);

          dp[nbm][j] = min(dp[nbm][j], dp[bm][i] + cost);
        }
      }
  dijkstra(n);

  bm = (1 << (k + 1)) - 1;
  int minim = MMAX * 100000 + 5;
  for(int i = 1; i <= k; i++)
    minim = min(minim, dmin[noduri[i]] + dp[bm][i]);
  printf("%d", minim);

  return 0;
}