Cod sursa(job #2840737)

Utilizator grecu_tudorGrecu Tudor grecu_tudor Data 28 ianuarie 2022 18:16:53
Problema Ubuntzei Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.78 kb
#include <fstream>
#include <queue>
#include <vector>
#include <cassert>
#include <iostream>
 
using namespace std;
 
ifstream fin( "ubuntzei.in" );
ofstream fout( "ubuntzei.out" );
 
const int INF = (int)1e9;
const int DIM = 2005;
const int MAXN = 19;

vector<pair<int, int>> G[DIM];
int stop[MAXN];
int cost[MAXN][MAXN];

int minCostCyc( int n ) {
  vector<vector<int>> dp((1 << n), vector<int>(n, INF));
  
  dp[1][0] = 0;
  for ( int mask = 1; mask < (1 << n); ++mask ) {
	if ( (mask & 1) == 0 ) continue;
	for ( int lst = 0; lst < n; ++lst ) {
	  for ( int nxt = 0; nxt < n; ++nxt ) {
		if ( (mask & (1 << nxt)) == 0 && cost[lst][nxt] != INF ) {
		  dp[mask + (1 << nxt)][nxt] = min(dp[mask + (1 << nxt)][nxt], dp[mask][lst] + cost[lst][nxt]);
		}
	  }
	}
  }
  assert(dp[(1 << n) - 1][n - 1] != INF);
  return dp[(1 << n) - 1][n - 1];
}

int dist[DIM];

void dijkstra( int b ) {  
  priority_queue<pair<int, int>> pq;
  pq.push({0, b});
  dist[b] = 0;
  while ( !pq.empty() ) {
    int u = pq.top().second;
    pq.pop();
	for ( auto ngh : G[u] ) {
	  if ( dist[u] + ngh.second < dist[ngh.first] ) {
		dist[ngh.first] = dist[u] + ngh.second;
		pq.push({-dist[ngh.first], ngh.first});
	  }
	}
  }
}

int main() {
  int n, m, k, u, v, c;
 
  fin >> n >> m >> k;
  for ( int i = 0; i < k; ++i ) {
	fin >> stop[i];
  }
  stop[k++] = 1; stop[k++] = n;
  while ( m-- ) {
	fin >> u >> v >> c;
	G[u].push_back({v, c});
	G[v].push_back({u, c});
  }
  for ( int i = 0; i < k; ++i ) {
	for ( int j = 0; j < k; ++j ) {
	  cost[i][j] = INF;
	}
  }
  for ( int i = 0; i < k; ++i ) {
	for ( int x = 1; x <= n; ++x ) {
      dist[x] = INF;
	}
	dijkstra(stop[i]);
	for ( int j = 0; j < k; ++j ) {
	  if ( i == j ) continue;
	  cost[i][j] = dist[stop[j]];
	}
  }
  fout << minCostCyc(k);
  fin.close();
  fout.close();
  return 0;
}