Cod sursa(job #2478428)

Utilizator aurelionutAurel Popa aurelionut Data 22 octombrie 2019 01:34:32
Problema Ubuntzei Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.34 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
#include <bitset>

using namespace std;

const int INF = (1 << 30);
const int NMAX = 2005;
const int KMAX = 20;
int nodes, edges, friends;
int friendnode[KMAX];
int dist[NMAX][NMAX];
int cost[NMAX];
vector < pair <int, int> > graph[NMAX];
int dp[17][(1 << 1) + 5];

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;
	}
};

void Dijkstra(int start)
{
	for (int i = 1;i <= nodes;++i)
		cost[i] = INF;
	cost[start] = 0;
	priority_queue <Heap> pq;
	bitset <NMAX> seen;
	pq.push(Heap(start, 0));
	while (!pq.empty())
	{
		Heap curr = pq.top();
		pq.pop();
		if (seen[curr.node] == 0)
		{
			seen[curr.node] = 1;
			for (auto &j : graph[curr.node])
			{
				if (cost[j.first] > cost[curr.node] + j.second)
				{
					cost[j.first] = cost[curr.node] + j.second;
					pq.push(Heap(j.first, cost[j.first]));
				}
			}
		}
	}
}

int main()
{
	ifstream fin("ubuntzei.in");
	ofstream fout("ubuntzei.out");
	fin >> nodes >> edges;
	fin >> friends;
	int pos = 0;
	for (int i = 1;i <= friends;++i)
	{
		int x;
		fin >> x;
		if (x == 1 || x == nodes)
			continue;
		friendnode[++pos] = x;
	}
	friendnode[0] = 1;
	friendnode[++pos] = nodes;
	friends = pos;
	for (int i = 1;i <= edges;++i)
	{
		int u, v, c;
		fin >> u >> v >> c;
		graph[u].push_back(make_pair(v, c));
		graph[v].push_back(make_pair(u, c));
	}
	for (int i = 0;i <= friends;++i)
	{
		Dijkstra(friendnode[i]);
		for (int j = 0;j <= friends;++j)
			dist[i][j] = cost[friendnode[j]];
	}
	for (int i = 0;i < friends;++i)
		for (int state = 0;state < (1 << friends);++state)
			dp[i][state] = INF;
	dp[0][1] = 0;
	for (int state = 1;state < (1 << friends);++state)
		for (int i = 0;i < friends;++i)
			if ((state & (1 << i)) != 0)
				for (int j = 0;j < friends;++j)
					if ((state & (1 << j)) == 0)
						dp[j][state | (1 << j)] = min(dp[j][state | (1 << j)], dp[i][state] + dist[i][j]);
	int answer = INF;
	for (int i = 0;i < friends;++i)
		answer = min(answer, dp[i][(1 << friends) - 1] + dist[i][friends]);
	fout << answer << "\n";
	fin.close();
	fout.close();
	return 0;
}