Cod sursa(job #611822)

Utilizator stocarulCosmin-Mihai Tutunaru stocarul Data 3 septembrie 2011 16:54:25
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.14 kb
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#define infile "ubuntzei.in"
#define outfile "ubuntzei.out"
#define nMax 2013
#define kMax 17
#define inf 1<<30

using namespace std;

vector < pair <int, int> > v[nMax];
vector <int> imp;
int ad[kMax][kMax];
int dp[1<<kMax][kMax];
int n, m, k;

void read() {
  scanf("%d %d\n", &n, &m);
  scanf("%d", &k);
  for(int i = 0; i < k; ++i) {
    int x;
    scanf("%d", &x);
    imp.push_back(x);
  }
  for(int i = 0; i < m; ++i) {
    int x, y, z;
    scanf("%d %d %d", &x, &y, &z);
    v[x].push_back(make_pair(y, z));
    v[y].push_back(make_pair(x, z));
  }
}

vector <int> bf(int x) {
  vector <int> dp(n + 1, inf);
  vector <bool> vz(n + 1, false);
  queue <int> q;

  q.push(x), dp[x] = 0, vz[x] = true;
  while(!q.empty()) {
    int x = q.front();
    vz[x] = false;
    q.pop();
    for(unsigned i = 0; i < v[x].size(); ++i)
      if(dp[x] + v[x][i].second < dp[v[x][i].first]) {
        dp[v[x][i].first] = dp[x] + v[x][i].second;
        if(vz[v[x][i].first] == false)
          q.push(v[x][i].first), vz[v[x][i].first] = true;
      }
  }

  return dp;
}

void init() {

  imp.insert(imp.begin(), 1);
  imp.push_back(n);
  k += 2;

  for(unsigned i = 0; i < imp.size(); ++i) {
    vector <int> dp = bf(imp[i]);
    for(unsigned j = 0; j < imp.size(); ++j)
      ad[i][j] = dp[imp[j]];//, printf("%d ", ad[i][j]);
    //printf("\n");
  }

  for(int i = 0; i < (1<<k); ++i)
    for(int j = 0; j < k; ++j)
      dp[i][j] = inf;
}

void solve() {

  queue < pair <int, int> > q;

  dp[1][0] = 0;
  q.push(make_pair(1, 0));

  while(!q.empty()) {
    pair <int, int> x = q.front();
    q.pop();
    for(int i = 0; i < k; ++i) {
      if(((x.first >> i)&1) == 0 && x.second != i && dp[x.first][x.second] + ad[x.second][i] < dp[x.first + (1<<i)][i]) {
        dp[x.first + (1<<i)][i] = dp[x.first][x.second] + ad[x.second][i];
        q.push(make_pair(x.first + (1<<i), i));
      }
    }
  }
}

void write() {
  printf("%d\n", dp[(1<<k)-1][k-1]);
}

int main() {
  freopen(infile, "r", stdin);
  freopen(outfile, "w", stdout);

  read();
  init();
  solve();
  write();

  fclose(stdin);
  fclose(stdout);
  return 0;
}