Cod sursa(job #674370)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 6 februarie 2012 04:47:38
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.48 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <cstring>
#include <cstdlib>

#define INF 0x17D7841
#define MAX_CITIES 20
#define MAXN 2001

using namespace std;

typedef unsigned short uint16;
typedef vector<vector<pair<uint16,int> > > Graph;

int cities[MAX_CITIES];
int distances[MAX_CITIES][MAXN];

template<typename T>
class CQueue
{
public:
	CQueue(const size_t cap) :
		current(0),
		capacity(cap),
		size(0)
	{
		Q = (T*)malloc((cap+1)*sizeof(T));
	}
	
	inline T front() const
	{
		return Q[current];
	}
	
	inline void push(const T& elem)
	{
		const size_t pos = (current+size) % capacity;
		size++;
		Q[pos] = elem;
	}
	
	inline void pop()
	{
		if (size != 0)
		{
			size--;
			current++;
			current %= capacity;
		}
	}
	
	inline bool empty() const
	{
		return (size == 0);
	}
	
	inline void clear()
	{
		current = 0;
		size = 0;
	}
	
	~CQueue()
	{
		free(Q);
	}

private:
	T* Q;
	size_t current;
	size_t capacity;
	size_t size;
};

class CHeap
{
private:
	uint16 size;
	vector<uint16> vIndexes;
	vector<pair<int,uint16> > vHeap;
	
	inline void swap(const uint16 first, const uint16 second)
	{
		vIndexes[vHeap[first].second]=second;
		vIndexes[vHeap[second].second]=first;
		pair<int,uint16> aux;
		aux=vHeap[first];
		vHeap[first]=vHeap[second];
		vHeap[second]=aux;
	}
	
	void siftUp(int index)
	{
		int parent=(index-1-!(index%2))>>1;
		while(parent>=0 && vHeap[index].first<vHeap[parent].first)
		{
			swap(parent,index);
			index=parent;
			parent=(index-1-!(index%2))>>1;
		}
	}
	
	void siftDown(int index)
	{
		int child1,child2;
		bool ord=true;
		child1=(index<<1)+1;
		child2=(index+1)<<1;
		while(ord && child1<size)
		{
			ord=false;
			if(child2<size)
			{
				if(vHeap[child1].first<vHeap[child2].first)
				{
					if(vHeap[child1]<vHeap[index])
					{
						swap(child1,index);
						index=child1;
						ord=true;
					}
				}
				else if(vHeap[child2].first<vHeap[index].first)
				{
					swap(child2,index);
					index=child2;
					ord=true;
				}
			}
			else if(vHeap[child1].first<vHeap[index].first)
			{
				swap(child1,index);
				index=child1;
				ord=true;
			}
			child1=(index<<1)+1;
			child2=(index+1)<<1;
		}
	}
public:

	CHeap() : size(0)
	{}

	void insert(const pair<int,uint16>& val)
	{
		vHeap.push_back(val);
		vIndexes.push_back(size++);
		siftUp(size-1);
	}
	
	inline void modify(const int pos, const pair<int,uint16>& val)
	{
		vHeap[pos]=val;
		siftUp(pos);
	}
	
	inline void remove(const int pos)
	{
		swap(pos,--size);
		vHeap.pop_back();
		siftDown(pos);
	}
	
	inline const pair<int,uint16>& getElement(const int pos) const
	{
		return vHeap[pos];
	}
	
	inline int getPos(const int index) const
	{
		return vIndexes[index];
	}
	
	inline bool empty() const
	{
		return (size==0);
	}
	
	void print()
	{
		for(unsigned int i=0; i<vHeap.size(); ++i)
		{
			cout<<"("<<vHeap[i].first<<" "<<vHeap[i].second<<") ";
		}
		cout<<endl;
	}
};

void Dijkstra(Graph& graph, const int n, const uint16 src, int* dist)
{
	CHeap heap;
	
	memset(dist,0x3f,n*sizeof(int));

	for (int i=0; i<n; ++i)
	{
		heap.insert(make_pair(INF,i));
		dist[i] = INF;
	}
	heap.modify(heap.getPos(src), make_pair(0,src));
	dist[src] = 0;
	
	while (!heap.empty())
	{
		const pair<int,uint16> node=heap.getElement(0);
		dist[node.second] = node.first;
		heap.remove(0);
		
		if (node.first == INF)
			break;
		
		for (vector<pair<uint16,int> >::iterator it=graph[node.second].begin(); it!=graph[node.second].end(); ++it)
		{
			const int alt = dist[node.second]+it->second;
			if (alt < dist[it->first])
			{
				dist[it->first] = alt;
				heap.modify(heap.getPos(it->first),make_pair(alt,it->first));
			}	
		}
	}
}

int main()
{
	int n, m, k;
	Graph graph;
	fstream fin("ubuntzei.in", fstream::in);
	fstream fout("ubuntzei.out", fstream::out);
	
	fin >> n >> m >> k;
	//cout << n << " " << m << " " << k << endl;
	
	graph.resize(n+1);
	
	for (int i=0; i<k; ++i)
	{
		fin >> cities[i];
		//cout << cities[i] << " ";
	}
	//cout << "\n";
	
	for (int i=0; i<m; ++i)
	{
		int x,y,z;
		fin >> x >> y >> z;
		
		//cout << x << " " << y << " " << z << "\n";
		
		graph[x-1].push_back(make_pair(y-1,z));
		graph[y-1].push_back(make_pair(x-1,z));
	}
	
	Dijkstra(graph, n, 0, distances[0]);
	
	if (0 == k)
	{	
		cout << distances[0][n-1] << "\n";
	}
	
	
	
	fin.close();
	fout.close();
	return 0;
}