Cod sursa(job #623387)

Utilizator dacyanMujdar Dacian dacyan Data 19 octombrie 2011 20:38:28
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.19 kb
#include <fstream>
#include <vector>
#include <set>
#include <climits>
#define DIM 10001
#define DIM_K 16
#define INF INT_MAX
using namespace std;

int n, m, k, sol(INF);
vector<pair<int, int> > G[DIM];
int c[DIM_K], path[DIM_K][DIM], sur[DIM];
int din[DIM_K][1<<DIM_K]; // cost min sa ajungi in nodul j dupa ce ai trecut prin i


void Read();
void Write();
void Dijkstra(int source, int* val);
bool Biti(int s, int nod); // nodul nod face parte din starea s
void Solve();

int main()
{
	Read();
	Solve();
	Write();
	return 0;
}

void Read()
{
	ifstream fin("ubuntzei.in");
	fin >> n >> m >> k;
	for (int i = 0; i < k; ++i)
		fin >> c[i];
	int x, y, cost;
	for (int i = 1; i <= m; ++i)
	{
		fin >> x >> y >> cost;
		G[x].push_back(make_pair(y,cost));
		G[y].push_back(make_pair(x,cost));
	}
	fin.close();
}

void Solve()
{
	Dijkstra(1, sur);
	if (!k) 
	{
		sol = sur[n];
		return;
	}
	
	for (int i = 0; i < k; ++i)
		Dijkstra(c[i], path[i]);
	
	int i, j;
	for (i = 1; i < (1<<k); ++i) 
	{
		for (j = 0; j < k; ++j)
			if ((1 << j) == i) // starea contine un singur element
				break;
		if (j < k && (1 << j) == i)
		{
			din[j][i] = sur[c[j]];
			continue;
		}
		for (j = 0; j < k; ++j)
		{
			din[j][i] = INF;
			if (Biti(i, j))
				for (int l = 0; l < k; ++l)
					if (l != j && Biti(i, l))
						din[j][i] = min(din[j][i], din[l][i-(1<<j)] + path[l][c[j]]);
		}
	}
	for (int i = 0; i < k; ++i)
		sol = min(sol, din[i][1<<k-1] + path[i][n]);
}

void Dijkstra(int source, int* val)
{
	set<pair<int, int> > T;
	set<pair<int, int> >::iterator it;
	
	for (int i = 1; i <= n; ++i) val[i] = INF;
	
	val[source] = 0;
	T.insert(make_pair(0, source));
	
	while (!T.empty())
	{
		it = T.begin(); 
		int nod = it->second;
		int v = it->first;
		T.erase(*it);
		for (int i = 0; i < G[nod].size(); ++i)
		{
			int son = G[nod][i].first;
			int dist = G[nod][i].second;
			if (val[son] > v + dist)
			{
				val[son] = v + dist;
				T.insert(make_pair(val[son], son));
			}
		}
	}
		
}

bool Biti(int s, int nod)
{
	return (s & (1<<nod));
}
	
void Write()
{
	ofstream fout("ubuntzei.out");
	fout << sol << '\n';
	fout.close();
}