Cod sursa(job #2077849)

Utilizator TincaMateiTinca Matei TincaMatei Data 28 noiembrie 2017 17:55:25
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 2000;
const int MAX_M = 10000;
const int MAX_K = 15;
const int INF = 1000000000;
int oras[MAX_K];

struct Edge {
  int a, b, cost;
  int other(int x) {
    return a ^ b ^ x;
  }
} edges[MAX_M];

struct mycmp {
  bool operator() (pair<int, int> a, pair<int, int> b) { return a.second > b.second; }
};

vector<int> graph[1+MAX_N];
priority_queue<pair<int, int>, vector<pair<int, int> >, mycmp> q;

int cost[1+MAX_N][1+MAX_N];
void dijkstra(int s) {
  memset(cost[s], 0x3f, sizeof(cost[s]));
  cost[s][s] = 0;
  q.push(make_pair(s, 0));
  while(!q.empty()) {
    pair<int, int> t = q.top();
    q.pop();
    int nod = t.first, c = t.second;
    if(c == cost[s][nod])
      for(auto it: graph[nod]) {
        int fiu = edges[it].other(nod);
        if(c + edges[it].cost < cost[s][fiu]) {
          cost[s][fiu] = c + edges[it].cost;
          q.push(make_pair(fiu, cost[s][fiu]));
        }
      }
  }
}

int dp[MAX_K][1<<MAX_K];
static inline int min(int a, int b) {
  if(a < b)
    return a;
  return b;
}

int main() {
  int n, m, k;
  FILE *fin = fopen("ubuntzei.in", "r");
  FILE *fout = fopen("ubuntzei.out", "w");
  fscanf(fin, "%d%d%d", &n, &m, &k);
  for(int i = 0; i < k; ++i)
    fscanf(fin, "%d", &oras[i]);
  for(int i = 0; i < m; ++i) {
    fscanf(fin, "%d%d%d", &edges[i].a, &edges[i].b, &edges[i].cost);
    graph[edges[i].a].push_back(i);
    graph[edges[i].b].push_back(i);
  }

  for(int i = 0; i < k; ++i)
    dijkstra(oras[i]);
  dijkstra(1);
  dijkstra(n);

  for(int i = 0; i < k; ++i)
    dp[i][1<<i] = cost[1][oras[i]];
  for(int st = 1; st < (1 << k); ++st) {
    for(int i = 0; i < k; ++i) {
      if((st & (st - 1)) > 0) {
        dp[i][st] = INF;
        if((1 << i) & st)
          for(int j = 0; j < k; ++j)
            if(((1 << j) & st) && i != j)
              dp[i][st] = min(dp[i][st], dp[j][st ^ (1 << i)] + cost[oras[j]][oras[i]]);
      }
    }
  }

  int rez = INF;
  if(k == 0)
    rez = cost[1][n];
  for(int i = 0; i < k; ++i)
    rez = min(rez, dp[i][(1 << k) - 1] + cost[oras[i]][n]);
  fprintf(fout, "%d", rez);
  fclose(fin);
  fclose(fout);
  return 0;
}