Cod sursa(job #2077844)

Utilizator TincaMateiTinca Matei TincaMatei Data 28 noiembrie 2017 17:54:20
Problema Ubuntzei Scor 80
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];
deque<int> q;
bool inq[1+MAX_N];

void push(int nod) {
  if(!inq[nod]) {
    inq[nod] = true;
    q.push_back(nod);
  }
}

int pull() {
  int nod = q.front();
  inq[nod] = false;
  q.pop_front();
  return nod;
}

int cost[1+MAX_N][1+MAX_N];
void bellman(int s) {
  memset(cost[s], 0x3f, sizeof(cost[s]));
  cost[s][s] = 0;
  push(s);
  while(!q.empty()) {
    int nod = pull();
    for(auto it: graph[nod]) {
      int fiu = edges[it].other(nod);
      if(cost[s][nod] + edges[it].cost < cost[s][fiu]) {
        cost[s][fiu] = cost[s][nod] + edges[it].cost;
        push(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 = 1; i <= n; ++i)
    bellman(i);

  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;
}