Cod sursa(job #9130)

Utilizator devilkindSavin Tiberiu devilkind Data 26 ianuarie 2007 20:14:28
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.81 kb
#include <stdio.h>
#define NMAX 15002
#define MMAX 30002

FILE *f = fopen("radiatie.in","rt"), *g = fopen("radiatie.out","wt");

struct lista{long int nod,cost;
             lista *urm;} *vf[NMAX], *arb[NMAX];
             
struct muchie{long int x,y,cost;} heap[MMAX];
struct nodai{long int min,poz;} AI[NMAX*4];

long int n,i,j,k,x,y,hash[NMAX],m,nrq,eul[NMAX*2],depth[NMAX*2],poz[NMAX];
long int mat[NMAX][40],stram[NMAX][40];

long int MAXX(long int a, long int b)
{
if (a>b) return a;
return b;}    

long int MINN(long int a,long int b)
{
if (a>b) return b;
return a;
}

void citire()
{
fscanf(f,"%ld %ld %ld",&n,&m,&nrq);
lista *p;
long int c;
for (i=1;i<=m;i++)
    {
    fscanf(f,"%ld %ld %ld",&x,&y,&c);
    
    p=new lista;
    p->nod=y;
    p->urm=vf[x];
    p->cost=c;
    vf[x]=p;
    
    p=new lista;
    p->nod=x;
    p->urm=vf[y];
    p->cost=c;
    vf[y]=p;
    }
}
    
void recheap(long int i)
{long int poz;
muchie aux;
poz=i;
if (heap[i*2].cost<heap[poz].cost&&i*2<=k) poz=i*2;
if (heap[i*2+1].cost<heap[poz].cost&&i*2+1<=k) poz=i*2+1;
if (poz!=i) {aux=heap[i];
            heap[i]=heap[poz];
            heap[poz]=aux;
            recheap(poz);
            }
}
    

void extract()
{
muchie aux;
aux=heap[1];
heap[1]=heap[k];
heap[k]=aux;
k--;
recheap(1);
}
    
void add()
{
muchie aux;
long int i=k;

while ((heap[i/2].cost>heap[i].cost)&&(i!=1))
      {aux=heap[i];
      heap[i]=heap[i/2];
      heap[i/2]=aux;
      i/=2;}
}
    
    
void prim()
{
lista *p;
for (i=1;i<=n;i++)
    hash[i]=0;
p=vf[1];
k=1;
while (p)
      {heap[k].x=1;
      heap[k].y=p->nod;
      heap[k].cost=p->cost;
      k++;
      p=p->urm;
      }
hash[1]=1;
k--;
for (i=k/2;i>=1;i--)
    recheap(i);
long int lst;
for (i=1;i<=n-1;i++)
    {
    p=new lista;
    p->nod=heap[1].x;
    p->cost=heap[1].cost;
    p->urm=arb[heap[1].y];
    arb[heap[1].y]=p;

    p=new lista;
    p->nod=heap[1].y;
    p->cost=heap[1].cost;
    p->urm=arb[heap[1].x];
    arb[heap[1].x]=p;

    hash[heap[1].y]=1;
    lst=heap[1].y;
    p=vf[heap[1].y];

    extract();
    while (p)
      {
      if (!hash[p->nod])
      {k++;
      heap[k].x=lst;
      heap[k].y=p->nod;
      heap[k].cost=p->cost;
      add();}
      p=p->urm;}
    }
   
}

long int tata[NMAX];

long int costm(long int x, long int y)
{
lista *p;
p=arb[x];
while (p->nod!=y)
      p=p->urm;
return p->cost;
}

long int querymax(long int x, long int dpth)
{
if (dpth==0) return 0;
if (dpth==1) return costm(x,tata[x]);
long int ptr=0;

for (;1 << ptr < dpth;ptr++);
ptr--;
long int max;
max=MAXX(mat[x][ptr],querymax(stram[x][ptr],dpth - (1 << ptr)));
return max;
}

long int qstram(long int nod, long int dpth)
{
if (dpth==1) return tata[nod];
if (dpth==0) return nod;
long int ptr=0;
for (;1 << ptr < dpth;ptr++);
ptr--;
return qstram(stram[nod][ptr],dpth - (1 << ptr));
}

void DF(long int x,long int t, long int dpth)
{
long max;
lista *p;
tata[x]=t;
eul[k]=x;
if (!poz[x]) poz[x]=k;

long int ptr=0;

for (; 1 << ptr <= dpth;ptr++)
    {stram[x][ptr]=qstram(tata[x], (1 << ptr) - 1);
    mat[x][ptr]=MAXX( costm(x,tata[x]) , querymax(tata[x],(1 << ptr) - 1));
    }

depth[k++]=dpth;
p=arb[x];
hash[x]=1;
while (p)
      {if (!hash[p->nod]) {DF(p->nod,x,dpth+1);
                           eul[k]=x;
			   depth[k++]=dpth;}
                          
      p=p->urm;
      }
}


void build(long int nod,long int st, long int dr)
{
long int mid;
if (st==dr) {AI[nod].min=depth[st];
	     AI[nod].poz=st;}
	else {
	     mid=(st+dr)/2;

	     build(nod*2,st,mid);
	     build(nod*2+1,mid+1,dr);

	     if (AI[nod*2].min<AI[nod*2+1].min)
		AI[nod]=AI[nod*2];
		else AI[nod]=AI[nod*2+1];
	     }
}
long int minim,pozmin;

void query(long int nod, long int st, long int dr,long int a, long int b)
{
if ((a<=st)&&(dr<=b)) {if (AI[nod].min<minim) {minim=AI[nod].min;
					   pozmin=AI[nod].poz;
					   }
		  }
		  else
		  if ((st<=a&&a<=dr)||(st<=b&&b<=dr))
			{long int mid;
			mid=(st+dr)/2;
			query(nod*2,st,mid,a,b);
			query(nod*2+1,mid+1,dr,a,b);
			}
}

void answer()
{
long int i,x,y,dpth,max1,max2;
for (i=1;i<=nrq;i++)
	{
	fscanf(f,"%ld %ld",&x,&y);
	minim=n+1;
	query(1,1,2*n-1,MINN(poz[x],poz[y]),MAXX(poz[x],poz[y]));
	dpth=depth[poz[x]]-depth[pozmin];
	max1=querymax(x,dpth);
	dpth=depth[poz[y]]-depth[pozmin];
	max2=querymax(y,dpth);
	fprintf(g,"%ld\n",MAXX(max1,max2));
	}
}


int main()
{
//citire - done
citire();

//prim - done
prim();

//vector de tati si parcurgere euler - done
//build matrix - DONE
for (i=1;i<=n;i++)
    hash[i]=0;
k=1;
DF(1,0,0);

//build AI - not done
build(1,1,2*n-1);

//answer queries - lca - not done
answer();
fclose(f);
fclose(g);
return 0;
}