Cod sursa(job #2203892)

Utilizator aurelionutAurel Popa aurelionut Data 13 mai 2018 16:14:20
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <fstream>
#include <algorithm>
#include <queue>
#include <bitset>
#include <vector>

using namespace std;

struct heap
{
	int node, cost;
	heap()
	{
		this->node = this->cost = 0;
	}
	heap(int node, int cost)
	{
		this->node = node;
		this->cost = cost;
	}
	inline bool operator<(const heap& other) const
	{
		return this->cost > other.cost;
	}
};

const int NMAX = 2010;
const int KMAX = 17;
const int INF = 2e9;
int n, m, k, ans = INF;
int friends[KMAX];
int dist[KMAX][KMAX];
int dp[KMAX][(1 << KMAX) + 10];
int costs[NMAX];
vector <pair <int, int> > graph[NMAX];
priority_queue <heap> pq;
bitset <NMAX> viz;

void Read()
{
	ifstream fin("ubuntzei.in");
	fin >> n >> m >> k;
	int p = 0, x, y, z;
	for (int i = 1;i <= k;++i)
	{
		fin >> x;
		if (x == 1 || x == n)
			continue;
		friends[++p] = x;
	}
	friends[0] = 1;
	friends[++p] = n;
	k = p;
	for (int i = 1;i <= m;++i)
	{
		fin >> x >> y >> z;
		graph[x].push_back(make_pair(y, z));
		graph[y].push_back(make_pair(x, z));
	}
	fin.close();
	fin.close();
}

void Dijkstra(int node)
{
	for (int i = 1;i <= n;++i)
		costs[i] = INF;
	costs[node] = 0;
	pq.push(heap(node, 0));
	viz.reset();
	heap x;
	while (!pq.empty())
	{
		x = pq.top();
		pq.pop();
		if (viz[x.node] == 0)
		{
			viz[x.node] = 1;
			for (auto i : graph[x.node])
			{
				if (costs[i.first] > costs[x.node] + i.second)
				{
					costs[i.first] = costs[x.node] + i.second;
					pq.push(heap(i.first, costs[i.first]));
				}
			}
		}
	}
}

void Solve()
{
	for (int i = 0;i <= k;++i)
		for (int j = 0;j <= k;++j)
			dist[i][j] = INF;
	for (int i = 0;i <= k;++i)
		for (int stare = 0;stare < (1 << k);++stare)
			dp[i][stare] = INF;

	for (int i = 0;i <= k;++i)
	{
		Dijkstra(friends[i]);
		for (int j = 0;j <= k;++j)
			dist[i][j] = costs[friends[j]];	
	}

	dp[0][1] = 0;
	for (int stare = 0;stare < (1 << k);++stare)
		for (int i = 0;i <= k;++i)
			if ((stare & (1 << i)) != 0)
				for (int j = 0;j <= k;++j)
					if (i != j && (stare & (1 << j)) == 0)
						dp[j][stare | (1 << j)] = min(dp[j][stare | (1 << j)], dp[i][stare] + dist[i][j]);

	int stare = (1 << k) - 1;
	for (int i = 0;i <= k;++i)
		ans = min(ans, dp[i][stare] + dist[i][k]);
}

void Write()
{
	ofstream fout("ubuntzei.out");
	fout << ans << "\n";
	fout.close();
}

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