Cod sursa(job #3310526)

Utilizator DobraVictorDobra Victor Ioan DobraVictor Data 14 septembrie 2025 18:23:33
Problema Ubuntzei Scor 75
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.6 kb
#include <iostream>
#include <fstream>
#include <stdint.h>
#include <vector>
#include <queue>

const int64_t MAX_N = 2000;
const int64_t MAX_K = 15;
const int64_t MAX_K_MASK = 1 << MAX_K;
const int64_t MAX_DIST = 1000000000000000000;

int64_t n, m, k;
std::vector<std::pair<int64_t, int64_t>> adj[MAX_N];
int64_t points[MAX_K];

std::priority_queue<std::pair<int64_t, int64_t>> q;
int64_t dists[MAX_N];

int64_t startDists[MAX_K], endDists[MAX_K], pairDists[MAX_K][MAX_K];
int64_t dp[MAX_K_MASK][MAX_K];

int64_t min(int64_t x, int64_t y) {
	return (x < y) ? x : y;
}
void Dijkstra(int64_t start) {
	for(int64_t i = 0; i != n; ++i)
		dists[i] = MAX_DIST;

	dists[start] = 0;
	q.push({ 0, start });

	while(!q.empty()) {
		std::pair<int64_t, int64_t> val = q.top();
		q.pop();

		if(val.first != dists[val.second])
			continue;

		for(std::pair<int64_t, int64_t> edge : adj[val.second]) {
			int64_t newDist = val.first + edge.second;

			if(newDist < dists[edge.first]) {
				dists[edge.first] = newDist;
				q.push({ newDist, edge.first });
			}
		}
	}
}

int main() {
	std::ifstream fin("ubuntzei.in");
	std::ofstream fout("ubuntzei.out");

	fin >> n >> m;
	fin >> k;
	for(int64_t i = 0; i != k; ++i) {
		fin >> points[i];
		--points[i];
	}
	for(int64_t i = 0; i != m; ++i) {
		int64_t x, y, z;
		fin >> x >> y >> z;
		--x; --y;

		adj[x].push_back({ y, z });
		adj[y].push_back({ x, z });
	}

	if(!k) {
		Dijkstra(0);
		fout << dists[n - 1];

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

		return 0;
	}

	Dijkstra(0);
	for(int64_t i = 0; i != k; ++i)
		startDists[i] = dists[points[i]];
	Dijkstra(n - 1);
	for(int64_t i = 0; i != k; ++i)
		endDists[i] = dists[points[i]];
	
	for(int64_t i = 0; i != k; ++i) {
		Dijkstra(points[i]);
		for(int64_t j = 0; j != k; ++j)
			pairDists[i][j] = dists[points[j]];
	}

	for(int64_t mask = 0; mask != (1 << k); ++mask) {
		for(int64_t i = 0; i != k; ++i)
			dp[mask][i] = MAX_DIST;
	}
	for(int64_t i = 0; i != k; ++i)
		dp[1 << i][i] = startDists[i];
	
	for(int64_t mask = 1; mask != (1 << k); ++mask) {
		if(!(mask & (mask - 1)))
			continue;
		
		for(int64_t i = 0; i != k; ++i) {
			if(!(mask & (1 << i)))
				continue;
			
			int64_t prevMask = mask ^ (1 << i);
			for(int64_t j = 0; j != k; ++j) {
				if(!(prevMask & (1 << j)))
					continue;
				
				dp[mask][i] = min(dp[mask][i], dp[prevMask][j] + pairDists[j][i]);
			}
		}
	}

	int64_t res = MAX_DIST;
	for(int64_t i = 0; i != k; ++i)
		res = min(res, dp[(1 << k) - 1][i] + endDists[i]);
	
	fout << res;

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

	return 0;
}