Cod sursa(job #1605238)

Utilizator qwertyuiTudor-Stefan Berbinschi qwertyui Data 18 februarie 2016 21:00:42
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.26 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>
#include <set>
#include <algorithm>

using namespace std;

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

#define MAXN 10005
#define MAXK 17
#define INFTY 0x3F3F3F3F

vector < pair <int, int> > edge[MAXN], edgeK[MAXK];
int dist[MAXK][1 << MAXK];

priority_queue < pair <int, int> > NodeQ;
priority_queue < pair <int, pair <int, int> > > queK;

vector <int> dijkstra(int src, int M, vector < pair <int, int> >* edge)
{
	vector <int> d(M, INFTY);
	vector < pair <int, int> >::iterator it;

	d[src] = 0;

	for (NodeQ.push(make_pair(-d[src], src)); !NodeQ.empty(); )
	{
		int u = NodeQ.top().second;
		int dq = -NodeQ.top().first;

		NodeQ.pop();

		if (d[u] < dq)
			continue;

		for (it = edge[u].begin(); it != edge[u].end(); ++ it)
		{
			int v = (*it).first;
			int cost = (*it).second;
			if (d[v] > d[u] + cost)
			{
				d[v] = d[u] + cost;
				NodeQ.push(make_pair(-d[v], v));
			}
		}
	}

	return d;
}

int dijkstraK(int src, int sink, int nodeCountK, vector < pair <int, int> >* edgeK)
{

	for (int i = 0; i < MAXK; ++i)
		for (int j = 0; j < (1<<MAXK); ++j)
			dist[i][j] = INFTY;

	dist[src][1 << src] = 0;

	for (queK.push(make_pair(0, make_pair(src, 1 << src))); !queK.empty(); )
	{
		int u = queK.top().second.first;
		int s = queK.top().second.second;
		int d = -queK.top().first;

		queK.pop();

		if (dist[u][s] < d)
			continue;

		for (vector < pair <int, int> >::iterator it = edgeK[u].begin(); it != edgeK[u].end(); ++ it)
		{
			int v = (*it).first;
			int cost = (*it).second;

			if (!(s & (1 << v)))
			{
				int t = s | (1 << v);
				if (dist[v][t] > dist[u][s] + cost) {
					dist[v][t] = dist[u][s] + cost;
					queK.push(make_pair(-dist[v][t], make_pair(v, t)));
				}
			}
		}
	}

	return dist[sink][(1 << nodeCountK) - 1];
}

int main()
{
	int M, N, subsetCount, u, v, cost;

	fin >> M >> N >> subsetCount;

	int src  = 0;
	int sink = M - 1;

	vector <int> subset(subsetCount), idxSubset(M);
	bitset <MAXN> inSubset;

	for (int i = 0; i < subsetCount; ++ i)
	{
		fin >> u;
		--u;
		idxSubset[subset[i] = u ]= i;
		inSubset[u] = true;
	}
	subset.push_back(src);
	idxSubset[src] = (int) subset.size() - 1;
	inSubset[src] = true;

	subset.push_back(sink);
	idxSubset[sink] = (int) subset.size() - 1;
	inSubset[sink] = true;

	for (int i = 0; i < N; ++ i)
	{
		fin >> u >> v >> cost;
		--u,
		--v;
		edge[u].push_back(make_pair(v, cost));
		edge[v].push_back(make_pair(u, cost));
	}

	vector <int> d;

	d = dijkstra(src, M, edge);

	for (int i = 0; i < d.size(); ++ i)
		if (inSubset[i])
			if ((int) i != src)
				edgeK[idxSubset[src]].push_back(make_pair(idxSubset[i], d[i]));

	if (subsetCount > 0)
	{
		for (int i = 0; i < subset.size(); ++ i)
			if (subset[i] != src && subset[i] != sink)
			{
				d = dijkstra(subset[i], M, edge);
				for (int j = 0; j < d.size(); ++j)
					if (inSubset[j])
						if (subset[i] != (int) j)
							edgeK[i].push_back(make_pair(idxSubset[j], d[j]));
			}
		int answer = dijkstraK(idxSubset[src], idxSubset[sink], subset.size(), edgeK);

		fout << answer << '\n';
	}
	else
		fout << d[M - 1] << '\n';

	return 0;
}