Cod sursa(job #982485)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 9 august 2013 12:10:37
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.24 kb

#include <cstdio>
#include <vector>
#include <utility>
#include <algorithm>
#include <cstring>
#include <bitset>
#include <queue>
#include <iostream>

const int MAX_N(2005);
const int MAX_K(16);
const int MAX_VALUE(0x3f3f3f3f);

int n, m, Result(MAX_VALUE);
std::vector<std::pair<int,int>> Graph [MAX_N];
int k;
int v [MAX_K];
int Cost [MAX_K] [MAX_K];
int Dp [MAX_K] [1 << MAX_K];
int Dist [MAX_N];

inline void Read (void)
{
	std::freopen("ubuntzei.in","r",stdin);
	std::scanf("%d %d",&n,&m);
	std::scanf("%d",&k);
	for (int i(0) ; i < k ; ++i)
		std::scanf("%d",&v[i]);
	for (int i(1), a, b, c ; i <= m ; ++i)
	{
		std::scanf("%d %d %d",&a,&b,&c);
		Graph[a].push_back(std::make_pair(b,c));
		Graph[b].push_back(std::make_pair(a,c));
	}
	std::fclose(stdin);
}

inline void Print (void)
{
	std::freopen("ubuntzei.out","w",stdout);
	std::printf("%d\n",Result);
	std::fclose(stdout);
}

inline void BellmanFord (int node)
{
	std::memset(Dist + 1,MAX_VALUE,sizeof(*Dist) * n);
	Dist[node] = 0;
	std::queue<int> queue;
	queue.push(node);
	std::bitset<MAX_N> Mark;
	Mark[node] = true;
	int i;
	while (!queue.empty())
	{
		i = queue.front();
		queue.pop();
		Mark[i] = false;
		for (auto it : Graph[i])
			if (Dist[i] + it.second < Dist[it.first])
			{
				Dist[it.first] = Dist[i] + it.second;
				if (!Mark[it.first])
				{
					queue.push(it.first);
					Mark[it.first] = true;
				}
			}
	}
}

inline void Compute (void)
{
	for (int i(0) ; i < k ; ++i)
	{
		BellmanFord(v[i]);
		for (int j(0) ; j < k ; ++j)
			Cost[i][j] = Dist[v[j]];
	}
}

inline int Bit (const int X)
{
	return 1 << X;
}

inline void Dynamic (void)
{
	BellmanFord(1);
	if (!k)
	{
		Result = Dist[n];
		return;
	}
	const int END(1 << (k + 1));
	int i, j, conf;
	for (i = 0 ; i < k ; ++i)
		std::memset(Dp[i],MAX_VALUE,sizeof(*Dp[i]) * (1 << (k + 1)));
	for (i = 0 ; i < k ; ++i)
		Dp[i][Bit(i)] = Dist[v[i]];
	for (conf = 0 ; conf < END ; ++conf)
		for (j = 0 ; j < k ; ++j)
			if (conf & Bit(j))
				for (i = 0 ; i < k ; ++i)
					if (!(conf & Bit(i)))
						Dp[i][conf | Bit(i)] = std::min(Dp[i][conf | Bit(i)],Dp[j][conf] + Cost[j][i]);
	BellmanFord(n);
	for (i = 0 ; i < k ; ++i)
		Result = std::min(Result,Dist[v[i]] + Dp[i][(1 << k) - 1]);
}

int main (void)
{
	Read();
	Compute();
	Dynamic();
	Print();
	return 0;
}