Cod sursa(job #3220244)

Utilizator DobraVictorDobra Victor Ioan DobraVictor Data 2 aprilie 2024 21:44:49
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.13 kb
#include <iostream>
#include <fstream>
#include <stdint.h>
#include <utility>
#include <vector>
#include <queue>

int64_t min(int64_t x, int64_t y) {
	return (x < y) ? x : y;
}

typedef std::pair<int64_t, int64_t> pair;
typedef std::vector<pair> vector;
typedef std::priority_queue<pair, vector, std::greater<pair>> queue;

const int64_t MAX_N = 2000;
const int64_t MAX_COST = 10000000000ll;
const int64_t MAX_K = 17;
const int64_t MAX_K_POW_2 = 1 << MAX_K;

vector adj[MAX_N];
int64_t cost[MAX_N];
queue q;

int64_t targets[MAX_K];
int64_t dists[MAX_K][MAX_K];
int64_t dp[MAX_K_POW_2][MAX_K];
int main() {
	std::ifstream fin("ubuntzei.in");
	std::ofstream fout("ubuntzei.out");

	int64_t n, m, k;
	fin >> n >> m >> k;

	++k;
	targets[0] = 0;
	for(int64_t i = 1; i != k; ++i) {
		fin >> targets[i];
		--targets[i];
	}
	targets[k] = n - 1;
	++k;

	for(int64_t i = 0; i != m; ++i) {
		int64_t x, y, c;
		fin >> x >> y >> c;
		--x; --y;
		adj[x].push_back({ y, c });
		adj[y].push_back({ x, c });
	}

	for(int64_t i = 0; i != k; ++i) {
		for(int64_t j = 0; j != n; ++j)
			cost[j] = MAX_COST;
		cost[targets[i]] = 0;

		q.push({ 0, targets[i] });
		while(!q.empty()) {
			pair val = q.top();
			q.pop();

			if(cost[val.second] < val.first)
				continue;
			
			for(pair next : adj[val.second]) {
				int64_t newCost = val.first + next.second;
				if(newCost >= cost[next.first])
					continue;
				
				cost[next.first] = newCost;
				q.push({ newCost, next.first });
			}
		}
		
		for(int64_t j = 0; j != k; ++j)
			dists[i][j] = cost[targets[j]];
	}

	int64_t kPow2 = 1 << k;
	for(int64_t i = 0; i != kPow2; ++i)
		for(int64_t j = 0; j != k; ++j)
			dp[i][j] = MAX_COST;
	
	dp[1][0] = 0;
	for(int64_t i = 3; i != kPow2; ++i) {
		if(!(i & 1))
			continue;
		
		for(int64_t j = 0; j != k; ++j) {
			if(!(i & (1 << j)))
				continue;
			
			for(int64_t x = 0; x != k; ++x) {
				if(!(i & (1 << x)) || j == x)
					continue;
				dp[i][j] = min(dp[i][j], dp[i ^ (1 << j)][x] + dists[x][j]);
			}
		}
	}

	fout << dp[kPow2 - 1][k - 1];

	fin.close();
	fout.close();

	return 0;
}