Cod sursa(job #695285)

Utilizator andunhillMacarescu Sebastian andunhill Data 28 februarie 2012 11:38:56
Problema Ubuntzei Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.75 kb
#include<fstream>
#include<vector>
#include<queue>
using namespace std;

#define INF 1073741824

ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");

int N, M, K;
vector<pair<int, int> >graph[2001];

int kloc[16];
bool isk[2001];
int A[2001][1025];

bool inq[2001][32768];

class cmp
{	public: bool operator()(pair<int, int> a, pair<int, int> b)
	{	return A[a.first][a.second] > A[b.first][b.second];
	}
};

priority_queue<pair<int, int>, vector<pair<int, int> >, cmp>q; 

typedef vector<pair<int, int> >::iterator it;

void init()
{	for(int i = 0; i <= N; i++)
		for(int j = 0; j <= 1<<K; j++)
			A[i][j] = INF;
}

int find(int node)
{	for(int i = 0; i < K; i++) if(kloc[i] == node) return i;
	return 0;
}

void Dijkstra(int node)
{	pair<int, int>p;
	int conf;
	
	init();
	
	A[node][0] = 0; inq[node][0] = true;
	q.push(make_pair(node, 0)); conf = 0;
	
	while(!q.empty())
	{	p = q.top(); q.pop();
		inq[p.first][p.second] = false;
		
		for(it i = graph[p.first].begin(); i != graph[p.first].end(); i++)
		{	if(isk[i->first]) conf = p.second | (1<<find(i->first));
			else conf = p.second;
			
			if(A[i->first][conf] > A[p.first][p.second] + i->second)
			{	A[i->first][conf] = A[p.first][p.second] + i->second;
				
				if(!inq[i->first][conf])
				{	inq[i->first][conf] = true;
					q.push(make_pair(i->first, conf));
				}
			}
		}
	}
}

int main()
{	int i, x, y, z;
	int last = 0;
	
	f>>N>>M;
	
	f>>K;
	for(i = 0; i < K; i++)
	{	f>>kloc[i];
		isk[kloc[i]] = true;
		last = last | 1<<i;
	}
	for(i = 1; i <= M; i++)
	{	f>>x>>y>>z;
		
		graph[x].push_back(make_pair(y, z));
		graph[y].push_back(make_pair(x, z));
	}
	
	Dijkstra(1);
	
	g<<A[N][last];
	
	f.close();
	g.close();
	return 0;
}