Cod sursa(job #632046)

Utilizator blue_phoenixPosea Elena blue_phoenix Data 10 noiembrie 2011 10:05:05
Problema Heapuri Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.41 kb
//min heap

#include <stdio.h>

#define MAXN 200005
#define INF 1000000010

struct nod{
  int nr,crono;
};

nod heap[MAXN];
 int poz[MAXN];//poz[i]=locul in heap pe care se afla al i-lea element introdus
int N=0;


void urca(int loc){
   int x;
   nod aux;
   while(((x=loc/2)!=0) && heap[loc].nr<heap[x].nr){
      //interschimb nodul de pe locul loc cu tatal sau
      poz[heap[x].crono]=loc;
      poz[heap[loc].crono]=x;
      aux=heap[loc];
      heap[loc]=heap[x];
      heap[x]=aux;
      loc=x;
   }
}

void coboara(int loc){
   //cobor in fiul cel mai mic dintre cei doi
   int x,min,dir;
   nod aux;

   do{
     min=INF;
     //daca are fiul din stanga
     if((x=2*loc)<=N){min=heap[x].nr;dir=0;}
         else return;//daca nu are fiu in stanga, clar nu are nici in dreapta=>e frunza, e ok unde e...
     //daca are si fiul din dreapta
     if((x=2*loc+1)<=N){
        if(min>heap[x].nr){min=heap[x].nr;dir=1;}
     }
     //o iau pe minima
     x=2*loc+dir;
     //interschimb locul loc co locul x
      poz[heap[x].crono]=loc;
      poz[heap[loc].crono]=x;
      aux=heap[loc];
      heap[loc]=heap[x];
      heap[x]=aux;
      loc=x;
   }while(min==MAXN);
}

int main(){
  FILE *fin=fopen("heapuri.in","r");
  FILE *fout=fopen("heapuri.out","w");
  int n,cod,x,crono=1;
  nod aux;
  fscanf(fin,"%d",&n);
  int i;
  for(i=0;i<n;i++){
     fscanf(fin,"%d",&cod);
     if(cod==1){
        //inserez
        fscanf(fin,"%d",&x);
        aux.nr=x; aux.crono=crono;
        heap[++N]=aux;
        poz[crono]=N;
        crono++;       
        urca(N);
        /*printf("inserez %d\n",x);
        printf("heapul: ");
        for(int j=1;j<=N;j++)printf("(%d,%d)",heap[j].nr,heap[j].crono);
        printf("\n");*/
     }
     if(cod==2){
        //sterg al x-lea element ca ordine cronologica....
        fscanf(fin,"%d",&x);
        //el se afla in heap pe locul poz[x];
        //printf("scot elementul %d %d\n",heap[poz[x]].nr,heap[poz[x]].crono);
           heap[poz[x]]=heap[N];
           N--;
           if(poz[x]>1 && heap[poz[x]].nr<heap[poz[x]/2].nr)urca(poz[x]);
           if(poz[x]<N && heap[poz[x]].nr>heap[poz[x]/2].nr)coboara(poz[x]);
        /*printf("heapul: ");
        for(int j=1;j<=N;j++)printf("(%d,%d)",heap[j].nr,heap[j].crono);
        printf("\n");*/
        poz[x]=0;//marchez ca acest nod nu mai e in heap...
     }

     if(cod==3){
        //afisez minimul
        fprintf(fout,"%d\n",heap[1].nr);
     }


  }
return 0;
}