Cod sursa(job #24509)

Utilizator megabyteBarsan Paul megabyte Data 2 martie 2007 18:22:38
Problema PScNv Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <stdio.h>
#include <stdlib.h>
#define NMAX 262144
#define INF "pscnv.in"
#define OUF "pscnv.out"
#define DAD(a) (a/2)
#define ST(a) (2*a)
#define DR(a) (2*a+1)
#define MAX(a,b) ((a>b)?(a):(b))
int min=1024,y,p[NMAX]={0},best[NMAX];
char bit[NMAX]={0};
FILE *in,*out;

struct nod
{
	int c,k;
	nod *next;
};
struct head
{
	nod *p,*q;
}list[NMAX];

struct heap
{
	int h[NMAX],dim;
	void init(){ dim=0; }
	void insert(int x);
	void rebuild(int i);
	void new_key(int x,int key);
	int min();
	void debugh()
	{
		int i;
		for(i=1;i<=dim;i++) printf("%d %d\n",h[i],p[h[i]]);
		printf("\n");
	}
}hp;
void heap::insert(int x)
{
	dim++;
	register int i;
	i=dim;
	while(i>1&&best[h[DAD(i)]]>best[x])
	{
		h[i]=h[DAD(i)];
		p[h[i]]=i;
		i=DAD(i);
	}
	h[i]=x;p[x]=i;
}
void heap::rebuild(int i)
{
	int st,dr,min;
	st=ST(i);
	dr=DR(i);
	if(st<=dim&&best[h[st]]<best[h[i]]) min=st;
	else min=i;
	if(dr<=dim&&best[h[dr]]<best[h[min]]) min=dr;
	if(min!=i)
	{
		st=p[h[i]];p[h[i]]=p[h[min]];p[h[min]]=st;
		st=h[i];h[i]=h[min];h[min]=st;
		rebuild(min);
	}
}
void heap::new_key(int x,int key)
{
	best[x]=key;
	rebuild(DAD(p[x]));
}
int heap::min()
{
	if(dim>0)
	{
		int min;
		min=h[1];
		h[1]=h[dim];p[h[1]]=1;
		dim--;
		rebuild(1);
		return min;
	}
	else return 0;
}
void kmin(int source)
{
	int nd,aux;
	nod *op;
	hp.init();
	hp.insert(source);
	while(hp.dim)
	{
		nd=hp.min();bit[nd]=1;
		op=list[nd].p;
		//printf("%d\n",nd);
		while(op!=NULL)
		{
			if(!bit[op->c])
			{
				bit[op->c]=1;
				best[op->c]=MAX(best[nd],op->k);
				hp.insert(op->c);
			//	hp.debugh();
			}
			else
			{
				aux=MAX(best[nd],op->k);
			//	printf("OLD: %d ",best[op->c]);
				if(aux<best[op->c]) hp.new_key(op->c,aux);
			//	printf("relax: %d %d %d\n",nd,op->c,best[op->c]);
			}
			op=op->next;
		}
	//	hp.debugh();
	}
}

int  main()
{
	int n,m,x,i,a,b,pd;
	nod *op;
	in=fopen(INF,"r");
	out=fopen(OUF,"w");
	fscanf(in,"%d %d %d %d",&n,&m,&x,&y);
	for(i=1;i<=n;i++){ list[i].p=list[i].q=NULL;best[i]=min;}
	for(i=1;i<=m;i++)
	{
		fscanf(in,"%d %d %d",&a,&b,&pd);
		if(a!=b)
                {
                op=new nod;
		op->c=b;op->k=pd;op->next=NULL;
		if(list[a].p==NULL) list[a].p=list[a].q=op;
		else {list[a].q->next=op;list[a].q=op;}
                }
		else if(a==x) best[x]=pd;
	}
//        for(i=1;i<=n;i++) best[i]=min;
	//best[x]=0;
	kmin(x);
//	for(i=1;i<=n;i++) printf("%d ",best[i]);
	fprintf(out,"%d",best[y]);
	fclose(in);fclose(out);
	return 0;
}