Cod sursa(job #1604049)

Utilizator ArkinyStoica Alex Arkiny Data 17 februarie 2016 22:01:31
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.93 kb
#include<fstream>
#include<vector>
#include<queue>
using namespace std;

#define Node pair<int,int>
#define mk make_pair
#define d first
#define c second

#define  MAX 2010
#define  INFINITY (1<<30)

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

struct Comparator
{
	bool operator () (Node const &e1, Node const &e2)
	{
		return e1.c > e2.c;
	}
};

vector<Node> L[MAX];
priority_queue<Node, vector<Node>, Comparator> H;

int D[MAX][MAX],O[MAX],N,M,K;
int E[30][1 << 18],S;
void Dijkstra(int S)
{
	D[S][S] = 0;
	H.push(mk(S, 0));
	while (H.size())
	{
		Node el = H.top();
		H.pop();
		

		for (int i = 0;i < L[el.d].size();++i)
		{
			if (el.c + L[el.d][i].c < D[S][L[el.d][i].d])
			{
				D[S][L[el.d][i].d] = el.c + L[el.d][i].c;
				H.push(mk(L[el.d][i].d, D[S][L[el.d][i].d]));
			}
		}

	}
}

int main()
{
	in >> N >> M >> K;

	for (int i = 1;i <= K;++i)
	{
		in >> O[i];
	}
	
	for (int i = 1;i <= M;++i)
	{
		int x, y, cost;
		in >> x >> y >> cost;
		L[x].push_back(mk(y, cost));
		L[y].push_back(mk(x, cost));
	}
	for (int j = 1;j <= N;++j)
		D[1][j] = INFINITY;
	Dijkstra(1);
	for (int i = 1;i <= K;++i)
	{
		for (int j = 1;j <= N;++j)
				D[O[i]][j] = INFINITY;

		Dijkstra(O[i]);

	}

	if (K == 0)
	{
		out << D[1][N];
		return 0;
	}

	for (int i = 1;i <= K;++i)
		E[i][1 << i] = D[1][O[i]];

	int state = 1 << K;
	for (int i = 1;i < state;++i)
	{
		S = i << 1;
		int nr = 0;
		for (int p = 1;p <= K + 1;++p)
			if ((1 << p)&S)
				++nr;
		if (nr == 1)
			continue;

		for (int j = 1;j <= K;++j)
		{
			E[j][S] = INFINITY;
			if (S&(1 << j) == 0)
				continue;
			for (int t = 1;t <= K;++t)
			{
				if (t != j && (S & (1 << t) != 0))
					E[j][S] = min(E[j][S], E[t][S^(1 << j)] + D[O[t]][O[j]]);
			}
		}
	}
	int rez = INFINITY;
	for (int i = 1;i <= K;++i)
	{
		rez = min(rez, E[i][S] + D[O[i]][N]);
	}
	
	out << rez;

	return 0;
}