Cod sursa(job #7004)

Utilizator mike4problemsRadu Gabriel mike4problems Data 21 ianuarie 2007 11:40:02
Problema Radiatie Scor 30
Compilator cpp Status done
Runda preONI 2007, Runda 1, Clasele 11-12 Marime 3.88 kb
#include<stdio.h>
#include<string.h>

#define In "radiatie.in"
#define Out "radiatie.out"

#define N 15001
#define M 30001

struct Mu
 {
 int x,y,c;
 char uz;
 } d[M];
int m,n,k;

int up[N];
int viz[N];
int c[N],st,end;
int h[M];
int gr[N];
int *g[N];
int *cost[N];

void creareheap(void);
int extract_min (int *);
void combheap(int, int);

void creareheap2(void);
int extract_min2 (int *);
void combheap2(int, int);

int getrep(int x)
{
	int y, tmp;

	for(y = x; up[y]; y = up[y]) ;
	while (x != y) {
		tmp = up[x];
		up[x] = y;
		x = tmp;
	}
	return(y);
}

void unify(int x, int y)
{
if (h[x]>h[y])
   up[y]=x;
   else
   { up[x]=y;
    if (h[y]==h[x]) h[y]++;
   }
}


int main()
{
 int i, j, rx, ry, nc, np, sm, j1;
 freopen(In,"r",stdin);
 freopen(Out,"w",stdout);
 scanf("%d%d%d",&n,&m,&k);
 for (i=1; i<=m; i++)
     {
     scanf("%d%d%d",&d[i].x,&d[i].y,&d[i].c);
     rx=getrep(d[i].x);
     ry=getrep(d[i].y);
     if (rx!=ry)
        unify(rx,ry);
     }
 for (nc=0, i=1;  i <=n; i++)
     if (!up[i]) nc++;
 memset(up,0,sizeof(up));
 creareheap(); sm=m;
 for(i=0,np=n-nc;i<np;)
  {
  j=extract_min(&m);
  rx=getrep(d[j].x);
  ry=getrep(d[j].y);
  if (rx!=ry)
   {
   i++;
   d[j].uz=1;
   gr[d[j].x]++,gr[d[j].y]++;
   unify(rx,ry);
   }
  }
 for(i=1;i<=n;i++)     {
  g[i]=new int[gr[i]];
  cost[i]=new int[gr[i]];}
 memset(gr,0,sizeof(gr));
 for(i=1;i<=sm;i++)
  if(d[i].uz)
   {
   g[d[i].x][gr[d[i].x]]=d[i].y;
   cost[d[i].x][gr[d[i].x]++]=d[i].c;
   g[d[i].y][gr[d[i].y]]=d[i].x;
   cost[d[i].y][gr[d[i].y]++]=d[i].c;
   }
 for(i=1;i<=k;i++)
  {
  scanf("%d%d",&rx,&ry);
  if(rx<ry) d[i].x=rx,d[i].y=ry;
  else d[i].x=ry,d[i].y=rx;
  }
 creareheap2();sm=k; j=k+1; d[j].x=n+1;
 while(sm)
  {
  j1=extract_min2(&sm);
  if(d[j].x==d[j1].x)
   {
   d[j1].c=viz[d[j1].y];
   continue;
   }
  j=j1;
  st=end=0;memset(viz,0,sizeof(viz)); memset(c,0,sizeof(c));
  c[st]=d[j].x;viz[d[j].x]=-1;
  while(st<=end)
   {
   rx=c[st++];
   for(i=0;i<gr[rx];i++)
    {
    ry=g[rx][i];
    if(!viz[ry])
     {
     if(cost[rx][i]>viz[rx])
      viz[ry]=cost[rx][i];
     else
      viz[ry]=viz[rx];
     c[++end]=ry;
     }
    }
   }
  d[j].c=viz[d[j].y];
  }
 for(i=1;i<=k;i++)
  printf("%d\n",d[i].c);
 return 0;
 }


void combheap (int i, int n)
{
 int fiu, tata, aux;
 tata = i; fiu = 2*i;
 while (fiu<=n)
     {
      if (fiu+1<=n)
          fiu = d[h[fiu]].c>d[h[fiu+1]].c?fiu+1:fiu;
      if (d[h[tata]].c>d[h[fiu]].c)
         {
          aux = h[tata];
          h[tata] = h[fiu];
          h[fiu] = aux;
          tata = fiu; fiu*=2;
         }
         else break;
     }
 }



void creareheap()
{
 int i;
 for (i=1; i<=m; i++) h[i]=i;
 for (i=m/2; i>0; i--)
     combheap(i,m);
}



int extract_min(int *n)
{
 int fiu, tata, aux, x;
 x=h[1]; h[1]=h[*n]; (*n)--;
 tata = 1; fiu = 2;
 while (fiu<=*n)
     {
      if (fiu+1<=*n)
      fiu = d[h[fiu]].c>d[h[fiu+1]].c?fiu+1:fiu;
      if (d[h[tata]].c>d[h[fiu]].c)
         {
          aux = h[tata];
          h[tata] = h[fiu];
          h[fiu] = aux;
          tata = fiu; fiu*=2;
         }
         else break;
      }
 return x;
}

void combheap2 (int i, int n)
{
 int fiu, tata, aux;
 tata = i; fiu = 2*i;
 while (fiu<=n)
     {
      if (fiu+1<=n)
          fiu = d[h[fiu]].x>d[h[fiu+1]].x?fiu+1:fiu;
      if (d[h[tata]].x>d[h[fiu]].x)
         {
          aux = h[tata];
          h[tata] = h[fiu];
          h[fiu] = aux;
          tata = fiu; fiu*=2;
         }
         else break;
     }
 }



void creareheap2()
{
 int i;
 for (i=1; i<=k; i++) h[i]=i;
 for (i=k/2; i>0; i--)
     combheap(i,k);
}



int extract_min2(int *n)
{
 int fiu, tata, aux, x;
 x=h[1]; h[1]=h[*n]; (*n)--;
 tata = 1; fiu = 2;
 while (fiu<=*n)
     {
      if (fiu+1<=*n)
      fiu = d[h[fiu]].x>d[h[fiu+1]].x?fiu+1:fiu;
      if (d[h[tata]].x>d[h[fiu]].x)
         {
          aux = h[tata];
          h[tata] = h[fiu];
          h[fiu] = aux;
          tata = fiu; fiu*=2;
         }
         else break;
      }
 return x;
}