Cod sursa(job #534249)

Utilizator marius21Marius Petcu marius21 Data 15 februarie 2011 15:23:37
Problema Algoritmul lui Dijkstra Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.73 kb
#include <cstdio>
#include <cstdlib>
#include <list>

using namespace std;

FILE *fin=fopen("dijkstra.in","r");
FILE *fout=fopen("dijkstra.out","w");

struct muchie
{
	int d,c;
};

list<muchie> a[50000];
int bif[50000];
int hp[50000];
int hpp[50000];
int hpn;
int d[50000];

inline bool hp_cmp(int a, int b)
{
	return d[hp[a]]<d[hp[b]];
}

inline void hp_swp(int a, int b)
{
	hp[a] = hp[a] ^ hp[b];
	hp[b] = hp[a] ^ hp[b];
	hp[a] = hp[a] ^ hp[b];
	hpp[hp[a]]=a;
	hpp[hp[b]]=b;
}

void hp_up(int i)
{
	while (i)
	{
		int t = ((i+1)>>1)-1;
		if (!hp_cmp(i, t))
			break;
		hp_swp(i, t);
	}
}

void hp_down(int i)
{
	while (1)
	{
		int min = i;
		int p1 = (i<<1)+1;
		int p2 = (i<<1)+2;
		if (p1<hpn && hp_cmp(p1, i))
			min = p1;
		if (p2<hpn && hp_cmp(p2, i))
			min = p2;
		if (min == i)
			break;
		hp_swp(i, min);
		i = min;
	}
}

inline int hp_pop()
{
	hpn--;
	hp_swp(0,hpn);
	hp_down(0);
	return hp[hpn];
}

inline int max(int a, int b)
{
	return a>b?a:b;
}

int main (int argc, char * const argv[]) {
	int n,m;
	fscanf(fin, "%d%d",&n,&m);
	for (int i=0; i<m; i++)
	{
		muchie tmp;
		int x,y;
		fscanf(fin, "%d%d%d",&x,&y,&tmp.c);
		x--; y--;
		tmp.d = y;
		a[x].push_back(tmp);
		tmp.d = x;
		a[y].push_back(tmp);
	}
	memset(bif,0,sizeof(int)*n);
	memset(d,0x3f,sizeof(int)*n);
	d[0] = 0;
	for (int i=0; i<n; i++)
	{
		hp[i] = i;
		hpp[i] = i;
	}
	hpn = n;
	while (hpn)
	{
		int cr = hp_pop();
		bif[cr] = 1;
		for (list<muchie>::iterator i = a[cr].begin(); i!=a[cr].end(); i++)
		{
			if (bif[i->d]) continue;
			if (d[cr]+i->c<d[i->d])
			{
				d[i->d] = d[cr]+i->c;
				hp_up(hpp[i->d]);
			}
		}
	}
	for (int i=1; i<n; i++)
	{
		if (d[i]>=0x3f3f3f3f)
			d[i] = 0;
		fprintf(fout, "%d ",d[i]);
	}
	fprintf(fout, "\n");
	fclose(fin);
	fclose(fout);
    return 0;
}