Mai intai trebuie sa te autentifici.

Cod sursa(job #444705)

Utilizator MciprianMMciprianM MciprianM Data 21 aprilie 2010 12:46:10
Problema Algoritmul lui Dijkstra Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 2.86 kb
# include <fstream>
# include <vector>

using namespace std;

const int maxn = 51000, inf = 2000000003;
int n, m;
vector <int> G [ maxn ], C [ maxn ];
int gSize [ maxn ], dist [ maxn ], from [ maxn ];
int heap [ maxn ], hSize, pos [ maxn ];
int viz [ maxn ];

void build_graph (){
	
	int i, x, y, c;
	ifstream f ( "dijkstra.in" );
	
	f >> n >> m;
	for ( i = 0; i < m; ++ i ){
		f >> x >> y >> c;
		G [ x ] . push_back ( y );
		C [ x ] . push_back ( c );
	}
	
	f . close ();
	
	for ( i = 1; i <= n; ++ i )
		gSize [ i ] = G [ i ] . size ();
	
}

void heapify ( int ps ){
	
	int md, mn, en, ips = ps;
	en = heap [ ps ];
	bool ok = true;
	while ( ok ){
		ok = false;
		md = dist [ heap [ ps ] ];
		mn = heap [ ps ];
		if ( ( ps <<= 1 ) <= hSize )
			if ( dist [ heap [ ps ] ] < md ){
				md = dist [ heap [ ps ] ];
				mn = heap [ ps ];
			}
		if ( ( ps |= 1 ) <= hSize )
			if ( dist [ heap [ ps ] ] < md ){
				md = dist [ heap [ ps ] ];
				mn = heap [ ps ];
			}
		if ( pos [ mn ] != ips ){
			swap ( heap [ pos [ mn ] ], heap [ ips ] );
			ips = ps = pos [ mn ];
			swap ( pos [ en ], pos [ mn ] );
			ok = true;
		}
	}
	
}

int extract_min(){
	
	int nd;
	nd = heap [ 1 ];
	heap [ 1 ] = heap [ hSize ];
	pos [ heap [ hSize ] ] = 1;
	-- hSize;
	viz [ nd ] = 2;
	
	heapify ( 1 );
	
	return nd;
}

void upHeap ( int ps ){
	
	int en, mn;
	en = heap [ ps ];
	while ( ps && dist [ heap [ ps / 2 ] ] > dist [ heap [ ps ] ] ){
		mn = heap [ ps / 2 ];
		swap ( heap [ ps ], heap [ ps / 2 ] );
		swap ( pos [ mn ], pos [ en ] );
		ps /= 2;
	}
	
}

void update_heap ( int nd ){
	
	upHeap ( pos [ nd ] );
	
}

void insert_heap ( int nd ){
	
	++ hSize;
	heap [ hSize ] = nd;
	pos [ nd ] = hSize;
	upHeap ( hSize );
	
}

void Dijkstra(){
	
	int i, minim;
	
	//init
	for ( i = 2; i <= n; ++ i ){
		dist [ i ] = inf;
		from [ i ] = -1;
	}
	dist [ 1 ] = 0;
	from [ 1 ] = 0;
	heap [ 1 ] = 1;
	hSize = 1;
	pos [ 1 ] =  1;
	
	//relax
	while ( hSize > 0 ){
		minim = extract_min ();  // removes the minimum dist node nd and returns nd; also decreases hSize and makes viz [ nd ] == 2
		for ( i = 0; i < gSize [ minim ]; ++ i )
			if ( viz [ G [ minim ] [ i ] ] < 2 && dist [ minim ] + C [ minim ] [ i ] < dist [ G [ minim ] [ i ] ] ){
				dist [ G [ minim ] [ i ] ] = dist [ minim ] + C [ minim ] [ i ];
				from [ G [ minim ] [ i ] ] = minim;
				if ( ! viz [ G [ minim ] [ i ] ] ){
					insert_heap ( G [ minim ] [ i ] );
					viz [ G [ minim ] [ i ] ] = 1;
				}
				else update_heap ( G [ minim ] [ i ] );
			}
	}
	
}

void afis (){
	
	ofstream g ( "dijkstra.out" );
	int i;
	
	for ( i = 2; i <= n; ++ i )
		if ( dist [ i ] != inf )
			g << dist [ i ] << ' ';
		else g << "0 ";
	g << '\n';
	
	g . close ();
	
}

int main (){
	
	build_graph ();
	Dijkstra ();
	afis ();
	
	return 0;
	
}