Cod sursa(job #876365)

Utilizator PetcuIoanPetcu Ioan Vlad PetcuIoan Data 11 februarie 2013 18:56:34
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.75 kb
#include<cstdio>
#include<cassert>
#include<cstring>
#include<cstdlib>

#include<vector>
#include<algorithm>
#include<queue>

#define f first
#define s second
#define mp make_pair
#define pb push_back

using namespace std;

const int kinf = 123456789;

int n, m, k, fr[20], cost[20][20], dp[17][150000];
vector<pair<int, int> > graph[2005];

void read(){
  assert(freopen("ubuntzei.in", "r", stdin));

  scanf("%d%d", &n, &m);
  fr[0] = 1;
  scanf("%d", &k);
  fr[k + 1] = n;
  for(int i = 1; i <= k; ++i)
    scanf("%d", &fr[i]);

  for(int i = 1; i <= m; ++i){
    int x, y, c;
    scanf("%d%d%d", &x, &y, &c);

    graph[x].pb(mp(c, y));
    graph[y].pb(mp(c, x));
  }
}

int dist[2005];

void init(){
  for(int i = 1; i <= n; ++i)
    dist[i] = kinf;
}

void blm(int start){
  init();

  dist[start] = 0;
  queue<int> q;
  q.push(start);

  int now;
  while(!q.empty()){
    now = q.front();
    q.pop();

    for(int i = 0; i < graph[now].size(); ++i)
      if(dist[now] + graph[now][i].f < dist[graph[now][i].s]){
        dist[graph[now][i].s] = dist[now] + graph[now][i].f;
        q.push(graph[now][i].s);
      }
  }
}

int lim;

void solve(){
  for(int i = 0; i <= k + 1; ++i){
    blm(fr[i]);
    for(int j = 0; j <= k + 1; ++j)
      cost[i][j] = dist[fr[j]];
  }

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

  dp[0][1] = 0;
  for(int i = 0; i < lim; ++i)
    for(int j = 1; j <= k; ++j)
      if((1 << j) & i)
        for(int t = 0; t <= k; ++t)
          if((1 << t) & i)
            dp[j][i] = min(dp[j][i], dp[t][i - (1 << j)] + cost[t][j]);
}

void write(){
  assert(freopen("ubuntzei.out", "w", stdout));

  printf("%d", dp[k][lim - 1]);
}

int main(){
  read();
  solve();
  write();

  return 0;
}