Cod sursa(job #2336856)

Utilizator dey44andIoja Andrei-Iosif dey44and Data 5 februarie 2019 16:44:11
Problema Ubuntzei Scor 45
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.74 kb
#include <fstream>
#include <iostream>
#include <algorithm>

#define input "ubuntzei.in"
#define output "ubuntzei.out"
#define NMAX 2005

using namespace std;

ifstream in(input);
ofstream out(output);

long long dist[NMAX][NMAX];
int N, M, K, nec[20], stiva[20];
bool uz[100005];
long long min_dist = 1000000000, local_dist;

void Read_Data()
{
	in >> N >> M >> K;
	for (int i = 1; i <= K; i++)
		in >> nec[i];
	sort(nec + 1, nec + K + 1);
	for (int i = 1; i <= M; i++)
	{
		int x, y, c;
		in >> x >> y >> c;
		dist[x][y] = dist[y][x] = c;
	}
}

void Floyd_Warshall()
{
	for (int k = 1; k <= N; k++)
	for (int i = 1; i <= N; i++)
	for (int j = 1; j <= N; j++)
	if (!dist[i][j])
	{
		if (dist[i][k] && dist[k][j])
			dist[i][j] = dist[i][k] + dist[k][j];
	}
	else
	{
		if (dist[i][k] && dist[k][j] && dist[i][k] + dist[k][j] < dist[i][j])
			dist[i][j] = dist[i][k] + dist[k][j];
	}
}

void BKT(int nivel)
{
	if (nivel > K)
	{
		local_dist += dist[stiva[K]][N];
		if (local_dist < min_dist)
			min_dist = local_dist;
		local_dist -= dist[stiva[K]][N];
	}
	else for (int i = 1; i <= K; i++)
	{
		int p = nec[i];
		if (nivel == 1 && !uz[p])
		{
			uz[p] = 1;
			stiva[nivel] = p;
			local_dist += dist[1][stiva[1]];
			BKT(nivel + 1);
			local_dist -= dist[1][stiva[1]];
			uz[p] = 0;
		}
		else if (!uz[p] && dist[stiva[nivel-1]][p])
		{
			uz[p] = 1;
			stiva[nivel] = p;
			local_dist += dist[stiva[nivel-1]][stiva[nivel]];
			BKT(nivel + 1);
			local_dist -= dist[stiva[nivel - 1]][stiva[nivel]];
			uz[p] = 0;
		}
	}
}

void Solve()
{
	if (!K) min_dist = dist[1][N];
	else BKT(1);
	out << min_dist << "\n";
}

int main()
{
	Read_Data();
	Floyd_Warshall();
	Solve();
	return 0;
}