Cod sursa(job #3329438)

Utilizator RaresHRares Hanganu RaresH Data 13 decembrie 2025 10:46:01
Problema Ubuntzei Scor 85
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.09 kb
#include <stdio.h>
#include <vector>
#include <queue>

FILE* fin;
FILE* fout;

const int MAX_N = 2000;
const int MAX_K = 15;
const int INF = 1e9;

struct Edge {
  int v, c;
};

struct State {
  int u;
  int d;

  bool operator <(const State& rhs) const {
    return d > rhs.d;
  }
};

int n, k;
int nodes[MAX_K];
std::vector<Edge> adj[MAX_N];
int dp[1 << MAX_K][MAX_K];
int dist[MAX_N][MAX_N];

void dijkstra(int source) {
  for(int i = 0; i < n; i++) {
    dist[source][i] = INF;
  }
  std::priority_queue<State> pq;
  pq.push({source, 0});
  dist[source][source] = 0;
  while(!pq.empty()) {
    auto [u, d] = pq.top();
    pq.pop();
    if(d == dist[source][u]) {
      for(auto [v, c] : adj[u]) {
        int new_d = d + c;
        if(new_d < dist[source][v]) {
          pq.push({v, new_d});
          dist[source][v] = new_d;
        }
      }
    }
  }
}

int main() {
  fin = fopen("ubuntzei.in", "r");
  fout = fopen("ubuntzei.out", "w");

  int m;
  fscanf(fin, "%d%d%d", &n, &m, &k);

  for(int i = 0; i < k; i++) {
    fscanf(fin, "%d", &nodes[i]);
    nodes[i]--;
  }

  for(int i = 0; i < m; i++) {
    int u, v, c;
    fscanf(fin, "%d%d%d", &u, &v, &c);
    u--;
    v--;
    adj[u].push_back({v, c});
    adj[v].push_back({u, c});
  }

  for(int u = 0; u < n; u++) {
    dijkstra(u);
  }

  if(k == 0) {
    fprintf(fout, "%d\n", dist[0][n - 1]);
    return 0;
  }

  for(int mask = 0; mask < (1 << k); mask++) {
    for(int i = 0; i < k; i++) {
      dp[mask][i] = INF;
    }
  }
  for(int i = 0; i < k; i++) {
    dp[1 << i][i] = dist[0][nodes[i]];
  }
  for(int mask = 0; mask < (1 << k); mask++) {
    for(int i = 0; i < k; i++) {
      if((mask >> i) & 1) {
        for(int j = 0; j < k; j++) {
          if(!((mask >> j) & 1)) {
            dp[mask | (1 << j)][j] = std::min(
              dp[mask | (1 << j)][j],
              dp[mask][i] + dist[nodes[i]][nodes[j]]
            );
          }
        }
      }
    }
  }

  int ans = INF;
  for(int i = 0; i < k; i++) {
    ans = std::min(ans, dp[(1 << k) - 1][i] + dist[nodes[i]][n - 1]);
  }

  fprintf(fout, "%d\n", ans);

  fclose(fin);
  fclose(fout);

  return 0;
}