Cod sursa(job #840382)

Utilizator arrayAnghel Mihai array Data 22 decembrie 2012 15:54:00
Problema Ubuntzei Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <cstring>
#define NMAX 2011
#define KMAX 16
using namespace std;

int N, M, K;
int sol = 2000000000;
vector<int> special;
vector< pair<int, int> > A[NMAX];
set< pair<int, int> > S;
int _dist[NMAX];
int dist[NMAX][NMAX];
bool ap[NMAX];
int dp[1 << KMAX][KMAX];

void read()
{
	ifstream fin("ubuntzei.in");
	int x, y, cost;
	fin >> N >> M >> K;
	special.push_back(1);
	for (int i = 0; i < K; ++i)
	{
		fin >> x;
		special.push_back(x);
	}
	special.push_back(N);
	K += 2;
	for (int i = 1; i <= M; ++i)
	{
		fin >> x >> y >> cost;
		A[x].push_back(make_pair(y, cost));
		A[y].push_back(make_pair(x, cost));
	}
}

void dijkstra(int start)
{
	while (S.size()) S.erase(*S.begin());
	S.insert(make_pair(0, start));
	for (int i = 0; i < NMAX; ++i) _dist[i] = 2000000000;
	for (int i = 0; i < NMAX; ++i) ap[i] = false;
	_dist[start] = 0;
	while (S.size())
	{
		int nod = S.begin()->second;
		S.erase(*S.begin());
		if (ap[nod]) continue;
		ap[nod] = true;
		for (vector< pair<int, int> >::iterator it = A[nod].begin(); it != A[nod].end(); ++it)
		{
			if (_dist[it->first] > _dist[nod] + it->second)
			{
				_dist[it->first] = _dist[nod] + it->second;
				S.insert(make_pair(_dist[it->first], it->first));
			}
		}
	}
}

void doit()
{
	for (int i = 1; i <= N; ++i)
	{
		dijkstra(i);
		for (int j = 1; j <= N; ++j)
		{
			dist[i][j] = _dist[j];
		}
	}
}

void dinamika()
{
	for (int i = 0; i < (1 << KMAX); ++i)
	{
		for (int j = 0; j < KMAX; ++j)
		{
			dp[i][j] = 2000000000;
		}
	}
	
	// 1  ,  nodurile  ,  N
	
	for (int i = 1; i < K; ++i)
	{
		dp[(1 << i) + 1][i] = dist[1][special[i]];
	}
	dp[0][0] = dp[1][0] = 0;
	int i, j, k;
	for (i = 1; i < (1 << K); i += 2)
	{
		for (int j = 0; j < K - 1; ++j)
		{
			if (dp[i][j] != 2000000000)
			{
				for (int k = 1; k < K; ++k)
				{
					if (!(i & (1 << k)))
					{
						dp[i | (1 << k)][k] = min(dp[i | (1 << k)][k], dp[i][j] + dist[special[j]][special[k]]);
					}
				}
			}
		}
	}
}

void write()
{
	ofstream fout("ubuntzei.out");
	for (int i = 0; i < K; ++i)
	{
		sol = min(sol, dp[(1 << K) - 1][i]);
	}
	fout << sol << '\n';
	cout << sol << '\n';
	fout.close();
}

int main()
{
	read();
	doit();
	dinamika();
	write();
	return 0;
}