Cod sursa(job #13060)

Utilizator moga_florianFlorian MOGA moga_florian Data 5 februarie 2007 15:34:07
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.45 kb
using namespace std;
#include<fstream>
#include<stdio.h>

int x[30004],y[30004],c[30004];
int t[15005],pd[15005],niv[15005];
int s[15005][16],v[15005][16];
char viz[15005];

struct nod{int vec, dist;nod* next;};
typedef nod* list;
list a[15005],z[15005];

void go(int k,int nv)
{
niv[k]=nv;
viz[k]=1;

list q;
for(q=a[k];q;q=q->next)
   if(viz[q->vec]==0)
      {
      s[q->vec][0]=k;
      v[q->vec][0]=q->dist;
      go(q->vec,nv+1);               
      }     
}     

int tata(int k)
{
while(k!=t[k])
   k=t[k];
return k;    
}

void intersc(int i,int j)
{
int aux;
aux=x[i];
x[i]=x[j];
x[j]=aux;

aux=y[i];
y[i]=y[j];
y[j]=aux;

aux=c[i];
c[i]=c[j];
c[j]=aux;     
}
     

int main()
{
FILE *fin=fopen("radiatie.in","r"),
     *fout=fopen("radiatie.out","w");
    
int m,n,i,j,p,cnt,k;
fscanf(fin,"%d%d%d",&n,&m,&p);

for(i=1;i<=m;i++)
   {
   fscanf(fin,"%d%d%d",&x[i],&y[i],&c[i]);              
   j=i;
   while(j/2&&c[j/2]<c[j])
      {
      intersc(j/2,j);
      j/=2;                    
      }
   }
   
i=m;
while(i>1)
 {
 intersc(1,i);
 i--;
 
 j=1;
 while(1)
  {
  k=2*j;
  if(k>i) break;
  if(k+1<=i&&c[k+1]>c[k]) k++;
  if(c[j]>c[k]) break;
  
  intersc(j,k);
  j=k;       
  }         
 }
 
//disjoint sets
int t1,t2;
for(i=1;i<=n;i++)
   t[i]=i,pd[i]=1;

cnt=0;
for(i=1;i<=m;i++)
   {
   t1=tata(x[i]);
   t2=tata(y[i]);              
   
   if(t1!=t2)
     {
     cnt++;
     x[cnt]=x[i];
     y[cnt]=y[i];
     c[cnt]=c[i];
             
     if(pd[t1]>pd[t2])
        t[t2]=t1;
     else
     if(pd[t1]<pd[t2])
        t[t1]=t2;
     else
       {
       t[t1]=t2;
       pd[t2]++;          
       }        
     }
   }
   
for(i=1;i<=cnt;i++)
   {
   if(a[x[i]]==NULL)
      a[x[i]]=z[x[i]]=new nod;
   else
      {
      z[x[i]]->next=new nod;
      z[x[i]]=z[x[i]]->next;                   
      }
   z[x[i]]->vec=y[i];
   z[x[i]]->dist=c[i];
   z[x[i]]->next=NULL;
   
   if(a[y[i]]==NULL)
      a[y[i]]=z[y[i]]=new nod;
   else
      {
      z[y[i]]->next=new nod;
      z[y[i]]=z[y[i]]->next;                    
      }   
   z[y[i]]->vec=x[i];
   z[y[i]]->dist=c[i];
   z[y[i]]->next=NULL;   
   }
   
memset(viz,0,sizeof viz);
s[1][0]=0;
v[1][0]=0;
go(1,1);

//matricile
for(j=1;j<=14;j++)
   for(i=1;i<=n;i++)
      {
      s[i][j]=s[s[i][j-1]][j-1];
      if(v[i][j-1]>v[s[i][j-1]][j-1])
         v[i][j]=v[i][j-1];
      else
         v[i][j]=v[s[i][j-1]][j-1];
      }
   
int i1,i2,sol;   
for(i=1;i<=p;i++)
  {
  fscanf(fin,"%d%d",&i1,&i2);
  if(niv[i1]<niv[i2])
      {
      int aux=i1;
          i1=i2;
          i2=aux;               
      }   
      
  sol=0;
  while(niv[i1]!=niv[i2])
      {
      k=niv[i1]-niv[i2];
      j=14;
      while(((1<<j)&k)==0) 
            j--;
      
      if(v[i1][j]>sol) sol=v[i1][j];
      i1=s[i1][j];
      }           
      
  while(i1!=i2)
     {
     k=14;
     while(k>=0&&s[i1][k]==s[i2][k]) k--;             
     
     if(k<0)
        {
        if(v[i1][0]>sol) sol=v[i1][0];
        if(v[i2][0]>sol) sol=v[i2][0];
        
        i1=i2;
        }
     else
        {
        if(v[i1][k]>sol) sol=v[i1][k];
        if(v[i2][k]>sol) sol=v[i1][k];
        
        i1=s[i1][k];
        i2=s[i2][k];            
        }
     }          
  
  fprintf(fout,"%d\n",sol);
  }
                 
fclose(fin);
fclose(fout);
return 0;
}