Cod sursa(job #2718312)

Utilizator hurjui12AlexandruHurjui Alexandru-Mihai hurjui12Alexandru Data 8 martie 2021 17:36:51
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.96 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

vector <pair <int, int>> v[2001];

struct el
{
	int nod, c;
	bool operator <(const el &alt) const
	{
		return c > alt.c;
	}
};

priority_queue <el> p;

int d[2001];
bool b[2001];

void dijkstra(int n, int s)
{
	int i, j, x, y;
	el na;
	
	while (p.empty() == 0)
		p.pop();
	for (i = 1; i<=n; i++)
	{
		d[i] = 1<<30;
		b[i] = 0;
	}
	d[s] = 0;
	p.push({s, 0});
	
	for (i = 1; i<n; i++)
	{
		while (b[p.top().nod])
			p.pop();
		na = p.top();
		b[na.nod] = 1;
		p.pop();
		
		for (j = 0; j<v[na.nod].size(); j++)
		{
			x = v[na.nod][j].first;
			y = v[na.nod][j].second;
			
			if (d[x] > na.c + y)
			{
				d[x] = na.c + y;
				p.push({x, d[x]});
			}
		}
	}
}

int cost[15][15];
vector <int> nr[16];

int dp[15][32768];
//dp[i][j] = costul minim pentru a trece prin nodurile indicate de parametrul i, daca ultimul nod prin care am trecut este j
//j este determinat in mod exclusiv de i in recurenta, adica bitul scos din i in recurenta este insusi j.

int main()
{
	int n, m, k, c[15];
	int i, j, x, y, z;
	fin >> n >> m >> k;
	for (i = 0; i<k; i++)
		fin >> c[i];
	for (i = 1; i<=m; i++)
	{
		fin >> x >> y >> z;
		v[x].push_back({y, z});
		v[y].push_back({x, z});
	}
	
	for (i = 0; i<k; i++)
	{
		dijkstra(n, c[i]);
		for (j = 0; j<k; j++)
			cost[i][j] = d[c[j]];
	}
	
	dijkstra(n, 1);
	
	if (k == 0)
	{
		fout << d[n];
		return 0;
	}
	
	for (i = 0; i < (1<<k); i++)
	{
		nr[__builtin_popcount(i)].push_back(i);
		for (j = 0; j<k; j++)
			dp[j][i] = 1<<30;
	}
	
	for (i = 0; i<k; i++)
		dp[i][1<<i] = d[c[i]];
	
	for (x = 2; x<=k; x++)
		for (y = 0; y<nr[x].size(); y++)
		{
			z = nr[x][y];
			for (i = 0; i<k; i++)
				if (z & (1<<i))
				{
					for (j = 0; j<k; j++)
						dp[i][z] = min(dp[i][z], dp[j][z ^ (1<<i)] + cost[i][j]);
				}
		}
	
	dijkstra(n, n);
	x = 1<<30;
	for (i = 0; i<k; i++)
		x = min(x, dp[i][(1<<k)-1] + d[c[i]]);
	fout << x;
	return 0;
}